Reputation: 188
I guess I'm not very good at regular expressions, so here is my problem (I'm sure it's easy to solve, but somehow I can't seem to find how )
var word = "aaa";
text = text.replace( new RegExp(word, "g"),
"<span style='background-color: yellow'>"+word+"</span>");
this is working in most cases.
What I want to do is for the regex ONLY TO WORK when word is not followed by the char / and not preceded with char ".
Upvotes: 8
Views: 10854
Reputation: 626689
First of all, the question can be interpreted as
"aaa
and aaa/
should match, same as "aaa/
) and as"aaa
, aaa/
should not match, while "aaa/
should).If you are using a JavaScript environment that supports ECMAScript 2018, you can use a lookbehind solution:
const word = 'aaa', // Word to find
left = '"', // Left-hand negative marker
right = '/', // Right-hand negative marker
text = 'aaa aaa/ "aaa "aaa/ aaaaa'; // Test string
// Relace any 'word' that does not start with " OR does not end with /
var regex = new RegExp(String.raw`\b(?<!${left})${word}\b(?!${right})`, 'g')
console.log( text.replace(regex, "<span style='background-color: yellow'>$&</span>") );
// => <span style='background-color: yellow'>aaa</span> aaa/ "aaa "aaa/ aaaaa
// Replace any 'word' that does not start with " AND does not end with /
var regex = new RegExp(String.raw`\b${word}\b(?!(?<=${left}${word})${right})`, 'g')
console.log( text.replace(regex, "<span style='background-color: yellow'>$&</span>") );
// => <span style='background-color: yellow'>aaa</span> <span style='background-color: yellow'>aaa</span>/ "<span style='background-color: yellow'>aaa</span> "aaa/ aaaaa
If you are using a JavaScript environment that does not support ECMAScript 2018, you can use
var word = 'aaa', // Word to find
left = '"', // Left-hand negative marker
right = '/', // Right-hand negative marker
text = 'aaa aaa/ "aaa "aaa/ aaaaa'; // Test string
// Relace any 'word' that does not start with " OR does not end with /, one match expected
var regex = new RegExp("([^" + left + "\\w]|^)(" + word + ")\\b(?!" + right + ")", 'g')
console.log( text.replace(regex, "$1<span style='background-color: yellow'>$2</span>") );
// => <span style='background-color: yellow'>aaa</span> aaa/ "aaa "aaa/ aaaaa
// Same as above, but in case "left" is a sequence of chars, not a single char, or a longer pattern:
var regex = new RegExp("(" + left + ")?\\b(" + word + ")\\b(?!" + right + ")", 'g')
console.log( text.replace(regex, function(x,g,gg) { return g ? x : "<span style='background-color: yellow'>" + gg + "</span>";}) );
// => <span style='background-color: yellow'>aaa</span> aaa/ "aaa "aaa/ aaaaa
// Replace any 'word' that does not start with " AND does not end with /, three matches expected
var regex = new RegExp("(" + left + word + right + ")|\\b" + word + "\\b", 'g')
console.log( text.replace(regex, function(x, g) { return g || "<span style='background-color: yellow'>" + x + "</span>";}) );
// => <span style='background-color: yellow'>aaa</span> <span style='background-color: yellow'>aaa</span>/ "<span style='background-color: yellow'>aaa</span> "aaa/ aaaaa
Note:
\b
, word boundary (and \w
construct in the negated character class in one of the workarounds)right
and left
chars/strings contain special regex metacharacters, mind to escape them before using as part of a regexword
variable, but in that case, if the word
starts or/and ends with a special regex metacharacter, word boundaries (\b
) will no longer work, you will need to use adaptive/dynamic word boundaries.Upvotes: 0
Reputation: 3332
You're going to want to use a negative look-ahead.
Regex: '[^"]' + word + '(?!/)'
Edit: While it doesn't matter as it appears you already found your answer by avoiding look-behinds, Rohit noticed something I didn't. You're going to need to capture the [^\"] and include it in the replace so that it does not get discarded. This wasn't necessary for the look-head since look-arounds by definition aren't included in captures.
Upvotes: 15
Reputation: 213203
You can use this regex: -
'([^"])' + word + '(?!/)'
and replace it with - "$1g"
Note that Javascript does not support look-behinds. So, you need to capture the previous character and ensure that it is not "
, using negated character class.
See demo at http://fiddle.re/zdjt
Upvotes: 4