Regex 在字符串中的特定位置仅查找一个匹配项

Regex 在字符串中的特定位置仅查找一个匹配项,regex,notepad++,Regex,Notepad++,我正在尝试处理一个大型生成日志,查找是否有复制操作转到错误的位置。我只是在用记事本++ 如果我有这样一个字符串: 第25672行:创建硬链接以将C:\DevDir\DERP\Output\x64\Release\someBin.dll复制到C:\DevDir\not\good\path\here\someBin.dll 还有这个 第25673行:创建硬链接以将C:\DevDir\not\good\path\here\someBin.dll复制到C:\DevDir\DERP\Output\x64\

我正在尝试处理一个大型生成日志,查找是否有复制操作转到错误的位置。我只是在用记事本++

如果我有这样一个字符串:

第25672行:创建硬链接以将C:\DevDir\DERP\Output\x64\Release\someBin.dll复制到C:\DevDir\not\good\path\here\someBin.dll

还有这个

第25673行:创建硬链接以将C:\DevDir\not\good\path\here\someBin.dll复制到C:\DevDir\DERP\Output\x64\Release\someBin.dll

这里的特殊单词是要查找的
DERP
。基本上,我需要查看
DERP
中的内容何时复制到非DERP位置,以及非DERP位置何时复制到DERP位置

所以我需要找到:

\scope\s
,然后
DERP
,然后
\sto\s
,然后不
DERP
到行尾

\s
,然后不是
DERP
,然后是
\sto\s
,然后是
DERP
,直到行尾

我已经尝试了几种不同的方法来让第一种起作用。在交换负面外观时,我认为我有第二个工作机会,但在手动滚动聚合结果后,我发现我在
to
的不正确一侧得到了
DERP

^.*?复制。*?DERP.*?到(?DERP)。*$

我不能使用仅根据
DERP
频率确定的答案,因为相对路径可能会导致
的一侧具有多个
DERP
s。这个相对路径子句正是我难以解释的地方

编辑:

嗯。。。进行了一些修补,这看起来很有希望:


(^.*?复制)(?>(?:(?!DERP.))*?to.*?DERP.*?$

好的,找到DERP,然后不找到DERP:

(^.*?复制)。*?DERP.*?到(?>(?:(?!DERP.)*?$)

要查找not DERP,然后查找DERP:

(^.*?复制)(?>(?:(?!DERP.))*?to.*?DERP.*?$

所以我想这里的答案是使用这种嵌套:

(?>(?:(?!ThingToNotFind)。)*?一些要查找的内容


如果有一种更优雅的方式来概括或表达这一点,我会接受这个答案。虽然我可以使用和修改它,但我很难查看这些嵌套模式并摸索它们。

好的,要找到DERP而不是DERP:

(^.*?复制)。*?DERP.*?到(?>(?:(?!DERP.)*?$)

要查找not DERP,然后查找DERP:

(^.*?复制)(?>(?:(?!DERP.))*?to.*?DERP.*?$

所以我想这里的答案是使用这种嵌套:

(?>(?:(?!ThingToNotFind)。)*?一些要查找的内容


如果有一种更优雅的方式来概括或表达这一点,我会接受这个答案。虽然我可以使用和修改它,但我很难查看和摸索这些嵌套模式。

也许您还应该使用
DERP
周围的路径分隔符来确保您真正查看的是完整的文件夹名称

解决方案一 这遵循问题编辑假定的正则表达式:

(^.*?复制)(?>(?:(!DERP.))*?to.*?DERP.*?$|(^.*?复制)。*?(DERP.*?to(?>(?:(!DERP.))*)

看看操场:

解决方案二 记事本++支持捕获组。因此,我会用它来获取所有错误的复制

查找:
(?:^((?!\\DERP\\)*$)|(?:^.*copy.*?(?:\\DERP\\).*到。*(?:\\DERP\\).$)|(^.*copy.*\\DERP\\\.$)|(?:^.*$)

替换:
\1

解释
(?:^(?(?!\\DERP\)*$)
这匹配不包含“\DERP\”的行,但不捕获它们

(?:^.*copy.*(?:\\DERP\\).*到。*(?:\\DERP\\).$)
将一个coppy的每个日志从一个DERP匹配到另一个DERP,但不捕获它

然后
(^.*copy.\\DERP\\.*$)
匹配并捕获带有一个或多个DERP文件夹的行,但是由于我们已经去掉了第一个表达式中带有两个或更多行的行,所以应该是安全的

然后,
(?:^.*$)
将所有其他行与非捕获表达式匹配,因此它们将被零替换,第一个非捕获部分也是如此


查看操场:

也许您还应该在
DERP
周围使用路径分隔符,以确保查看的是完整的文件夹名称

解决方案一 这遵循问题编辑假定的正则表达式:

(^.*?复制)(?>(?:(!DERP.))*?to.*?DERP.*?$|(^.*?复制)。*?(DERP.*?to(?>(?:(!DERP.))*)

看看操场:

解决方案二 记事本++支持捕获组。因此,我会用它来获取所有错误的复制

查找:
(?:^((?!\\DERP\\)*$)|(?:^.*copy.*?(?:\\DERP\\).*到。*(?:\\DERP\\).$)|(^.*copy.*\\DERP\\\.$)|(?:^.*$)

替换:
\1

解释
(?:^(?(?!\\DERP\)*$)
这匹配不包含“\DERP\”的行,但不捕获它们

(?:^.*copy.*(?:\\DERP\\).*到。*(?:\\DERP\\).$)
将一个coppy的每个日志从一个DERP匹配到另一个DERP,但不捕获它

然后
(^.*copy.\\DERP\\.*$)
匹配并捕获带有一个或多个DERP文件夹的行,但是由于我们已经去掉了第一个表达式中带有两个或更多行的行,所以应该是安全的

然后,
(?:^.*$)
将所有其他行与非捕获表达式匹配,因此它们将被零替换,第一个非捕获部分也是如此


检查操场:

你能在“to”上拆分行,然后在两个子串上检查DERP的匹配情况吗?你的意思是用
\K
或其他什么来拆分吗?请记住,根据标签/说明,这是用于记事本++。我个人不明白为什么这不起作用,但目标是捕捉整个字符串,这意味着这可能会变得丑陋。。。我不会阻止你的!如果在r中使用
(?!DERP)