Reputation: 94101
I have a string like so:
<p>Year: ={year}</p>\
<p>Director: ={director}</p>\
<ul>@{actors}<li class="#{class}">={actor}</li>{actors}</ul>\
And I want to extract all ={match}
that are NOT inside @{word}...{word}
, so in this case I want to match ={year}
and ={director}
but not ={actor}
. This is what I got so far but it's not working.
/(?!@.*)=\{([^{}]+)\}/g
Any ideas?
Edit: My current solution is to find all ={match}
inside @{}...{}
and replace the =
with something like =&
. Then I grab the ones that are outside and finally I come back and replace the flagged ones back to their original state.
Upvotes: 4
Views: 657
Reputation: 10169
here you go, needed to negative look ahead the ending {whatever}
also
/(?!@.*)=\{([^{}]+)\}(?!.*\{[^{}]+\})/g
Previous only works for {match}
per line.
Hooking on @
would actually mean a LookBehind and it is difficult to use LookBehind in this case because LookBehind likes very much to know exactly how many chars to look for.
So let's use LookAhead for looking ahead: =\{([^{}]+)\}(?![^@]*[^=@]{)
with hooking on the end {tag}
Edit: demo http://regex101.com/r/zH7uY6
Upvotes: 0
Reputation: 173522
You can use regular expressions to break down the string into segments, like so:
var s = '<p>Year: ={year}</p> \
<p>Director: ={director}</p> \
<ul>@{actors}<li class="#{class}">={actor}</li>{actors}</ul>',
re = /@\{([^}]+)\}(.*?)\{\1\}/g,
start = 0,
segments = [];
while (match = re.exec(s)) {
if (match.index > start) {
segments.push([start, match.index - start, true]);
}
segments.push([match.index, re.lastIndex - match.index, false]);
start = re.lastIndex;
}
if (start < s.length) {
segments.push([start, s.length - start, true]);
}
console.log(segments);
Based on your example, you would get these segments:
[
[0, 54, true],
[54, 51, false],
[105, 5, true]
]
The boolean indicates whether you're outside - true
- or inside a @{}...{}
segment. It uses a back-reference to match the ending against the start.
Then, based on the segments you can perform replacements as per normal.
Upvotes: 3