gpt4 book ai didi

c# - 正则表达式中的双重否定回顾

转载 作者:行者123 更新时间:2023-12-01 13:55:34 25 4
gpt4 key购买 nike

我正在过滤掉 SQL 脚本中包含特定人员 ID 的行。就我的目的而言,过分热心过滤总比过分热心好,但我还是要小心一点。

例如,如果其中一个人的 ID 是 123 , 一行包含 [blob_id] = 123 ,我不想过滤掉它。所以,我想找到 123 (两边都有单词分隔符)只要它前面没有 [<some_id_here>] =或者,<some_id_here> = person_id .

正则表达式应匹配以下每一行:

123
[person_id] = 123
blah,blah,123,blah

并且它不应该匹配以下每一行:

foo123bar
[blob_id] = 123

我认为这个正则表达式可以工作:

(?<!\[(?!person_id)\] = )\b123\b

外部否定后视表示“字符串前面不能有 [<some_id_here>] =”。内部预测说“这个字符串可以匹配除 person_id 之外的任何东西。我认为双重否定意味着“如果这个字符串前面有 [<some_id_here>] = , <some_id_here>只能是 person_id .

不幸的是,情况似乎并非如此。它适用于我所有的测试用例,除了 [blob_id] = 123 .

我相信正在发生的事情是,出于某种原因,由于双重否定,外在的后视匹配任何东西。

这是我的 regex101 link和我的测试用例。

最佳答案

由于您要过滤掉整行,因此更容易:如果您在一行中发现不需要的内容,则可以丢弃该行。

如果您正在使用 PCRE,您可以使用回溯动词来实现您想要的:

\bblob_id\b.+(*SKIP)(*FAIL)|\b123\b

Demo

如果正则表达式引擎遇到blob_id在一行中,它将匹配到行尾 ( .+ ),然后匹配失败并从失败的位置重新开始尝试 ( (*SKIP)(*FAIL) )。这是可行的,因为引擎总是尝试从左到右的替代方案。


在 C# 中,您没有 (*SKIP)(*FAIL) ,因此您可以改用它:

\bblob_id\b.+|(?<id>\b123\b)

检查 match.Groups["id"].Success .如果为假,则将火柴扔掉。

但 C# 中的最佳替代方案是... 使用可变长度后视(C# 正则表达式引擎的一项重要功能):

\b123\b(?<!\bblob_id\b.*)

Demo

我将断言放在匹配之后只是为了优化,因此引擎实际上只会在它已经匹配\b123\b 时才检查lookbehind。成功。


看来我误解了这个问题:

In your second demo, the only <some_id_here> that it filters out is blob_id. I need it to filter out any id that isn't person_id.

好吧,在那种情况下,您需要放回那些括号以说明什么是 ID 以及什么是其他东西。我想我可以利用它们,因为您在问题中正是这样做的。那么双重否定环视就有意义了:

\b123\b(?<!\[(?!person_id\b)\w+\][^\]\n]*)

Demo

[^\]\n]表示 ] 之外的任何字符和换行符,因此您只会获得最接近搜索值的标识符。

关于c# - 正则表达式中的双重否定回顾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30874712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com