Negative regex
I have a line like:
<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 combine ={year} and ={director} , but not ={actor} . This is what I got so far, but it does not work.
/( ?!@. *)=\{([^{}]+)\}/g Any ideas?
Edit: My current solution is to find everything ={match} inside @{}...{} and replace = with something like =& . Then I grab those that are outside, and finally I go back and replace the flags with the original state.
You can use regular expressions to break the string into segments, for example:
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 will get the following segments:
[ [0, 54, true], [54, 51, false], [105, 5, true] ] Boolean means that you are outside - true - or inside the @{}...{} segment. It uses a backlink to match the ending with the beginning.
Then, based on the segments, you can perform replacements as normal.
here you go, you need to look negatively towards the end {whatever} also
/( ?!@. *)=\{([^{}]+)\}(?!.*\{[^{}]+\})/g
UPDATE:
The previous one works only for {match} in a string.
Binding to @ actually means LookBehind, in which case LookBehind is hard to use because LookBehind really likes to know exactly how many characters to look for.
So, let LookAhead look for perspective: =\{([^{}]+)\}(?![^@]*[^ =@ ]{) with the connection to the end {tag}
Edit: demo http://regex101.com/r/zH7uY6