假设我有以下正则表达式:
Console.writeline.+(?!;)
我想查找任何包含“console.writeline”的行,后跟任意字符一次或多次,但不以分号结尾。
当我使用以下字符串测试此正则表达式时:
Console.WriteLine("Final total count of missing VMs: {0}", missingVms.Count);
很匹配。但是该字符串以分号结尾,所以它不应该不匹配吗?
我意识到我可以使用[^;]
,但我更好奇为什么寻找分号似乎不适用于.NET中的负向先行
编辑:澄清一下:
假设我正在使用 Visual Studio 的查找和替换工具,并且我想查找并注释掉 Console.WriteLine(...)
的每个实例。但是,我可能会遇到 Console.WriteLine(...)
跨越多行的情况,如下所示:
Console.WriteLine("Adding drive to VM with ID: {0}. Drive HostVMID is {1}",
vm.ID, drive.HostVmId);
这些可以持续 2、3、4 等行,最后以 );
结束以关闭语句。然后我可以有其他行,后面紧跟着重要的代码块:
Console.WriteLine("Creating snapshot for VM: {0} {1}", dbVm.ID, dbVm.VmName);
dbContext.Add(new RTVirtualMachineSnapshot(dbVm));
所以我想做的是提出一个正则表达式语句,它将找到 Console.WriteLine
的第一种类型的实例以及它的简单单行实例。
我从这个问题的答案之一得到的正则表达式是
Console\.writeline(?>.+)(?<!;)
它将匹配任何包含 Console.WriteLine
但不以分号结尾的行。不过,我需要它继续,直到它最终确实到达右括号,后跟分号。
我尝试过以下正则表达式:
(Console\.writeline(?>.+)(?<!\);)
但是我认为这是不正确的,因为它仍然只匹配第一行,并且当写入行跨越多行时不会捕获以下行。
最终,我希望能够使用 Visual Studio 的查找和替换功能捕获完整 Console.writeline 语句,无论它跨越多少行,但我有点困惑我需要使用正则表达式来执行此操作。
最佳答案
您可以将以下正则表达式与lookbehind结合使用:
Console\.writeline(?>.+)(?<!;)
这是一个demo (注意不区分大小写的标志)
您使用的正则表达式Console.writeline.+(?!;)
检查 ;
仅在最后一个字符之后返回 true 并且您得到整行匹配。回顾(?<!;)
将检查 ;
行尾之前。但要确保与最后一个 ;
一致不匹配,需要使用原子组(?>.+)
以避免走回头路。如果您不使用原子组,则会发生回溯,并且将测试最后一个字符并返回部分匹配。
更新
注释掉Console.WriteLine
VS 中的查找和替换您可以使用
Console\.writeline\s*\([\s\S\r]+?\);(?=$|\r?\n)
或者(相同,但是符合展开循环技术,带有可选的空格以使其更安全):
Console\.writeline\s*\([^)]*(?:\)(?!\s*;\s*(?:$|\r?\n))[^)]*)*\)\s*;\s*(?=$|\r?\n)
并替换为
/* $0 */
在 VS 查找和替换中,您应该使用 [\s\S\r]
匹配包括换行符在内的任何符号。
关于c# - .NET 正则表达式查找分号时的负向前瞻,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34185524/