Reputation: 369
I have a single string of words, in which each word is separated by a newline character. I've used RegEx replacements to insert '{' and '}' characters around common prefixes and suffixes. The result looks like this:
{con}descens{ion}
lumberjack
tim{ing}
{tox}{icity}
fish
{dis}pel
What I'm trying to figure out is how I can perform a RegEx replace on this string that will only match text not between the '{' and '}' characters. I have further replacements to make, and each time I do, I'll be placing the '{' and '}' characters around the matches; I just don't wan't previous replacements (or pieces thereof) to be matched when performing new replacements. I know how to match "not '{'", for example, but I don't know how to match "not between '{' and '}'"
To put it into perspective, an example next replacement operation here would be to to replace all 'n' characters with '7' characters. In this case, the first line of the string, "{con}descens{ion}", should become "{con}desce{7}s{ion}" and not "{co{7}}desce{7}s{io{7}}"; the other words would remain the same based on these criteria.
Any suggestions?
Upvotes: 9
Views: 15482
Reputation: 70732
Assuming your curly braces will always be balanced, you can use a Negative Lookahead here.
[a-zA-Z]+(?![^{]*\})
Note: This only matches characters of the A
to Z
range, if words will include whitespace or you have other characters that need to be allowed or unsure of the type of input, you can use a negated match here.
[^}]+(?![^{]*\})
Upvotes: 16
Reputation: 338228
In a regular expression engine that supports variable length look-behind, that's easy:
(?<=^|\})[^{]+
In one that does not support look-behind (or fixed-length look-behind only) it's a little different:
(^|})([^{])
Here you must use both groups: group 1 contains nothing or a }
, depending on the position of the match, group 2 contains the actual match. If you make replacements, make sure you re-insert the contents of group 1.
Note that this answer does not not work for nested constructs.
Upvotes: 5