I have an application with a large number of #if debug blocks which kind of look like the the one below:
#if DEBUG
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.WriteLine("oldXml: " + oldXml.OuterXml);
Logging.开发者_运维问答Log("XmlDiff: " + diff_sb.ToString());
Console.ForegroundColor = ConsoleColor.Cyan;
Logging.Log("2XmlDiff: " + diff_sb.ToString());
Console.WriteLine("newXml: " + newXml.OuterXml);
Console.ForegroundColor = ConsoleColor.Green;
#endif
I am using Resharper's search pattern matching function and I need to be able to find all instances of the string "Logging.Log" inside of these if debug blocks
Would anyone know what the regex for this pattern search should be?
Probably one of the easier ways to do this is in two steps. First, use a regex to collect all the blocks of text between #if DEBUG
and #endif
. Then go through each one of those blocks and find the string "Logging.Log".
If you want to preserve exact position, you'll have to save the offset for each chunk in the first step and add the offsets in the second step.
(?<=#if DEBUG(?:(?!#endif\b).)*)Logging\.Log[^\r\n]*(?=.*#endif)
will match Logging.Log
and whatever else follows on that line only if it's between #if DEBUG
and #endif
. Note that you need to use RegexOptions.Singleline
for this to work. This regex relies on a feature that only few regex engines have, namely infinite repetition inside lookbehind assertions. Fortunately, .NET is among those.
In C#:
StringCollection resultList = new StringCollection();
Regex regexObj = new Regex(@"(?<=#if DEBUG(?:(?!#endif\b).)*)Logging\.Log[^\r\n]*(?=.*#endif)", RegexOptions.Singleline);
Match matchResult = regexObj.Match(subjectString);
while (matchResult.Success) {
resultList.Add(matchResult.Value);
matchResult = matchResult.NextMatch();
}
Explanation:
# from the current position, look behind in the string to check...
(?<= # whether it is possible to match...
#if DEBUG # the literal text # if DEBUG
(?: # followed by...
(?!#endif\b) # (as long as we can't match #endif along the way)
. # any character
)* # any number of times
) # end of lookbehind assertion.
Logging\.Log # Then match Logging.Log,
[^\r\n]* # followed by any character(s) except newlines.
(?= # as long as there is (further up ahead)...
.*#endif # any number of characters, followed by #endif
) # end of lookahead
If you're sure that every #if DEBUG
ends with an #endif
, then you can drop the (?=.*#endif)
.
精彩评论