chopper draw lion4
chopper draw lion4

Reputation: 13507

Regex: Adding negative cases with lookaheads

I have the following regex from here:

/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/

This regex is designed to match 2 underscores and the text between them. For example:

var regex = /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/;
var string = '_omgbbq_';
regex.exec(string);
>>>["_omgbbq_", "omgbbq", undefined]

However, I want to add an additional rule - if there is a backslash before the underscore then it should ignore it. For example:

var string = '_omg\\_bbq_'
regex.exec(string)
>>>["_omgbbq_", "omgbbq", undefined]

What's the best way to add a negative case to this regex so that it ignores underscores which are followed by a backslash? My inclination is to use a lookahead, but this regex is so complicated I am not sure where to insert it without messing anything up. Where in this regex can I add a lookahead to detect and ignore a negative case?

Upvotes: 2

Views: 66

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627537

You can use

var regex = /^_(?=\S)([\s\S]*?[^\s\\])_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/;
                              ^^^^^^^

I expanded the \S to a negated character class [^\s] and added a \ into it so that we do not match the closest _ if it is preceded with a backslash.

If you need to also match strings like *omg\*bbq* (see the second alternative in the regex you have), you can use the same technique:

var regex = /^_(?=\S)([\s\S]*?[^\s\\])_(?!_)|^\*(?=\S)([\s\S]*?[^\s\\])\*(?!\*)/;

var regex = /^_(?=\S)([\s\S]*?[^\s\\])_(?!_)|^\*(?=\S)([\s\S]*?[^\s\\])\*(?!\*)/g;
var string = "_omg\\_bbq_ ";
console.log(string.match(regex));
string = "*omg\\*bbq*";
console.log(string.match(regex));

Upvotes: 2

Related Questions