Reputation: 2202
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.
Upvotes: 6
Views: 6689
Reputation: 195
If you're doing things with Syntax Highlighting, you really should take a look at this CodeProject article: Fast Colored TextBox for Syntax Highlighting This project is about a Code Editor window that does syntax highlighting too, and it uses regular expressions. Maybe it does what you need (and maybe more). It seems like the author of this has given a lot of thought to the Syntax Highlighting. I tried the foreach that you talked about here, and the "foreach" if it is part of a comment, and it displayed nicely.
Upvotes: 1
Reputation: 10347
Try this:
^\s*(?<!//.*)\s*foreach
for c# code analysis try reliable and opensource Irony - .NET Language Implementation Kit from codeplex.
Upvotes: 1
Reputation: 31781
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)
Upvotes: 5
Reputation: 689
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.
Upvotes: 1