Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex - negative look-behind anywhere on line

How do I match a pattern only if there isn't a specific character before it on the same line?

I have the following regex code:

pattern = @"(?<=^|[\s.(<;])(?<!//)(" + Regex.Escape(keyword) + @")(?=[\s.(>])";
replacement = "<span style='" + keywordStyle + "'>$1</span>";
code = Regex.Replace(code, pattern, replacement);

I would like to add a criteria to only match if there aren't 2 slashes before it on the same line (C# comment).

I played around with it, and modified the pattern:

pattern = @"(?<!\/\/)(?<=^|[\s.(<;])(?<!//)(" + Regex.Escape(keyword) + @")(?=[\s.(>])";

But apparently this only works if the 2 slashes are 2 characters right before the keyword.

So this pattern wouldn't match "//foreach", but would match "// foreach".

Can negative look-behinds be used in this case, or can I accomplish this some other way, besides negative look-behinds?

Thank you.

EDIT:

Guess I wasn't clear enough. To reiterate my problem:

I'm working on syntax highlighting, and I need to find matches for c# keywords, like "foreach". However, I also need to take into account comments, which are defined by 2 slashes. I don't want to match the keyword "foreach" if it is part of a comment (2 slashes anywhere before it on the same line.

The negative lookbehind doesn't help me in this case because the slashes will not necessarily be right before the keyword, for example "// some text foreach" - I don't want this foreach to match.

So again, my question is: How can modify my pattern to only match if 2 slashes aren't anywhere before it on the same line?

Hope my question is clear now.

like image 891
Rivka Avatar asked Aug 12 '12 19:08

Rivka


People also ask

How do you write negative lookahead in regex?

The negative lookahead construct is the pair of parentheses, with the opening parenthesis followed by a question mark and an exclamation point. Inside the lookahead, we have the trivial regex u. Positive lookahead works just the same. q(?=

How do you use negative Lookbehind regex?

Negative Lookbehind Syntax:Where match is the item to match and element is the character, characters or group in regex which must not precede the match, to declare it a successful match. So if you want to avoid matching a token if a certain token precedes it you may use negative lookbehind. For example / (? <!

What is look around in regex?

As we've seen, a lookaround looks left or right but it doesn't add any characters to the match to be returned by the regex engine. Likewise, an anchor such as ^ and a boundary such as \b can match at a given position in the string, but they do not add any characters to the match.

Does JavaScript support negative Lookbehind?

Since 2018, Lookbehind Assertions are part of the ECMAScript language specification. As Javascript supports negative lookahead, one way to do it is: reverse the input string. match with a reversed regex.


2 Answers

Simplifying your regex pattern a bit, what about the following? It makes use of the non-greedy match on "//" plus 0 or more characters thereafter.

(?<!//.*?)(?<Keyword>foreach)
like image 108
David Andres Avatar answered Oct 25 '22 20:10

David Andres


Without knowing exactly what you're attempting it's hard to say the best solution but most likely it's simply checking the beginning of the line for // before you bother trying the regex, especially if there can be more than one keyword per line.

like image 1
Nic Wolfe Avatar answered Oct 25 '22 20:10

Nic Wolfe