Reputation: 1399
Given the string; "{abc}Lorem ipsum{/abc} {a}dolor{/a}"
I want to be able find occurrences of curly brace "tags", store the tag and the index where it was found and remove it from the original string. I want to repeat this process for each occurrence, but because I'm removing part of the string each time the index must be correct...I can't find all the indices THEN remove them at the end. For the example above, what should happen is;
Given this logic, "{/abc}" should be found at index 11 - since "{abc}" has already been removed.
I basically need to know where those "tags" start and end without actually having them as part of the string.
I'm almost there using regular expressions but it sometimes skips occurrences.
let BETWEEN_CURLYS = /{.*?}/g;
let text = '{abc}Lorem ipsum{/abc} {a}dolor{/a}';
let match = BETWEEN_CURLYS.exec(text);
let tags = [];
while (match !== null) {
tags.push(match);
text = text.replace(match[0], '');
match = BETWEEN_CURLYS.exec(text);
}
console.log(text); // should be; Lorem ipsum dolor
console.log(tags);
/**
* almost there...but misses '{a}'
* [ '{abc}', index: 0, input: '{abc}Lorem ipsum{/abc} {a}dolor{/a}' ]
* [ '{/abc}', index: 11, input: 'Lorem ipsum{/abc} {a}dolor{/a}' ]
* [ '{/a}', index: 20, input: 'Lorem ipsum {a}dolor{/a}' ]
*/
Upvotes: 2
Views: 944
Reputation: 626690
You need to subtract the match length from the regex lastIndex
value, otherwise the next iteration starts farther than expected (since the input becomes shorter, and the lastIndex
does not get changed after you call replace
to remove the {...}
substring):
let BETWEEN_CURLYS = /{.*?}/g;
let text = '{abc}Lorem ipsum{/abc} {a}dolor{/a}';
let match = BETWEEN_CURLYS.exec(text);
let tags = [];
while (match !== null) {
tags.push(match);
text = text.replace(match[0], '');
BETWEEN_CURLYS.lastIndex = BETWEEN_CURLYS.lastIndex - match[0].length; // HERE
match = BETWEEN_CURLYS.exec(text);
}
console.log(text); // should be; Lorem ipsum dolor
console.log(tags);
Some more RegExp#exec
reference to bear in mind:
If your regular expression uses the "
g
" flag, you can use theexec()
method multiple times to find successive matches in the same string. When you do so, the search starts at the substring ofstr
specified by the regular expression'slastIndex
property (test()
will also advance thelastIndex
property).
Upvotes: 3