I have two types of strings. If a string contains foo first and later bar, it shouldn’t be touched. If it contains only bar, then bar, should be replaced by qux.
"sometext foo someothetext bar somethirdtext"shouldn’t be touched"sometext bar someothetext"=>"sometext qux someothetext"
It looks like I need to use negative look behind, but I can’t get it working correctly. Currently, I have an expression:
str.gsub! (/(?<!foo)(.*)bar/), '\1qux'
However, it replaces bar to qux in both strings. I have a feeling that .* screws things up. I wasn’t able to find a look behind example where look behind group doesn’t precede matched group immediately.
If you could use variable length lookbehinds, you could just replace matches of
/(?<!foo.*)bar/with'qux'.Without support for variable length lookbehinds, you can really use a lookbehind at all because you can’t know the position to start the lookbehind to find
foo. Here is how you can do it with a lookahead:Explanation:
This performs the negative lookahead
(?!foo)at each character until we matchbar, so it will not match strings wherefoocomes beforebar.The anchor to the beginning of the string is necessary because if you can start in the middle of the string it will just start the match immediately after the
finfoo. The multiline option is used so that the.character will match line breaks, not sure if this is necessary for what you are doing.