I have a string and need to end up with an object that count all apples for every name, my struggle was to get separate match for each apple they took
In the part <@Viktor><@Kate>took:apple::apple:
I want to get two matches instead of 1, and more if there would be more apples like <@Viktor><@Kate>took:apple::apple::apple::apple:
const message = 'I had :apple::apple::apple::apple: :apple:<@Viktor><@Kate>took:apple::apple: and later <@viktor> took again:apple:but not <@kate>';
const result {
viktor: 3,
kate: 2
}
used this to handle the problem, but it wasn`t accepted by the interviewer coz I used join&split later. The task was to solve this problem only with regexp.
function countGifts(text) {
let result = {}
let names = ['viktor', 'kate']
names.forEach(name=>{
let regex = new RegExp(`(${name}).*?(:apple:)+`, "gi")
result[name] = text.match(regex).join('').split(':apple:').length-1
})
return result
}
console.log(
countGifts(message)
);
I`m new to regexp, and would appreciate alternative solutions and hints for articles with complex examples, coz all I found was pretty easy
2
Answers
I’ll assume that if multiple name tags follow each other with maybe some separation text, but not
:apple:
, they will all get the apples that follow. I will also assume that if a name tag is duplicated in such a list, the duplication will be ignored. So<@Victor><@Victor> :apple:
would assign one apple to Victor, not two.Here is one way to do that:
If you can use PCRE compatible regex (e.g. python with the regex library, or PHP) you could use this regex (using viktor as a sample name):
This will match:
(?:<@viktor>(?:<@)?+|G(?<!^))
: either<@viktor><?
: literally<@viktor>
, followed by(?:<@)?+
an optional start of a name tag; orG(?<!^)
: the end of the previous match (alternate use ofG
to match beginning of string disallowed by negative lookbehind)(?:(?!<@).)*?
: a minimal number of characters, none of which are at the start of a name tag (a tempered greedy token):apple:
: literally:apple:
Regex demo on regex101
Python usage:
Output:
PHP usage:
Output:
Demo on 3v4l.org