Regex lookahead、lookbehind和原子组

xpszyzbs  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(88)

我在我的正则表达式体中发现了这些东西,但我不知道我可以用它们来做什么。有没有人能举个例子让我试着理解他们是如何工作的?

(?=) - positive lookahead
(?!) - negative lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group
uubf1zoe

uubf1zoe1#

示例

给定字符串foobarbarfoo

bar(?=bar)     finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar)     finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar    finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar    finds the 2nd bar ("bar" which does not have "foo" before it)

您也可以将它们合并组合在一起:

(?<=foo)bar(?=bar)    finds the 1st bar ("bar" with "foo" before it and "bar" after it)

定义

向前看正(?=)

找到表达式A,其中表达式B如下:

A(?=B)

前瞻负(?!)

求表达式A,其中表达式B不跟随:

A(?!B)

看后面正(?<=)

在表达式B之前查找表达式A:

(?<=B)A

看负(?<!)背后

查找表达式A,其中表达式B不在前面:

(?<!B)A

原子组(?>)

原子组退出组,并在组内的 * 第一个 * 匹配模式之后丢弃替代模式(禁用回溯)。

  • 应用于foots(?>foo|foot)s将匹配其第一个备选foo,然后失败,因为s没有立即跟随,并停止回溯被禁用

非原子组将允许回溯;如果随后的匹配失败,它将回溯并使用替代模式,直到找到整个表达式的匹配或所有可能性都被用尽。

  1. (foo|foot)s应用于foots将:
    1.匹配其第一个备选foo,然后失败,因为sfoots中没有立即跟随,并回溯到其第二个备选;
    1.匹配它的第二个替代foot,然后成功,因为s紧接着foots,然后停止。

部分资源

在线测试人员

42fyovps

42fyovps2#

查找区是零宽度Assert。它们检查正则表达式(朝向当前位置的右边或左边-基于前面或后面),当找到匹配时成功或失败(基于它是正的还是负的),并丢弃匹配的部分。它们不消耗任何字符--它们后面的正则表达式(如果有的话)的匹配将从相同的光标位置开始。
阅读regular-expression.info了解更多详情。

  • 积极前瞻:

语法:

(?=REGEX_1)REGEX_2

仅当REGEX_1匹配时才匹配;在匹配REGEX_1之后,丢弃该匹配,并且在相同的位置开始搜索REGEX_2。
举例说明:

(?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}

REGEX_1是[a-z0-9]{4}$,它匹配四个字母数字字符,后跟行尾。
REGEX_2是[a-z]{1,2}[0-9]{2,3},它匹配一个或两个字母,后跟两个或三个数字。
REGEX_1确保字符串的长度确实为4,但不消耗任何字符,因此搜索REGEX_2从同一位置开始。现在REGEX_2确保字符串匹配其他一些规则。如果没有前瞻,它将匹配长度为3或5的字符串。

  • 负向先行

语法:

(?!REGEX_1)REGEX_2

仅当REGEX_1不匹配时才匹配;在检查REGEX_1之后,对REGEX_2的搜索在相同的位置开始。
举例说明:

(?!.*\bFWORD\b)\w{10,30}$

前瞻部分检查字符串中的FWORD,如果找到则失败。如果它没有找到FWORD,则向前查找成功,并且下面的部分验证字符串的长度在10和30之间,并且它只包含单词字符a-zA-Z0-9_
Look-behind与look-ahead类似:它只是在当前光标位置后面查找。一些正则表达式风格,如JavaScript不支持后向Assert。大多数支持它的风格(PHP,Python等)都要求后向部分具有固定的长度。

  • 一旦令牌匹配,原子组基本上丢弃/忘记组中的后续令牌。查看此页面以获取atomic groups的示例
bvjxkvbb

bvjxkvbb3#

为什么-假设你正在玩Wordle,你输入了“ant”。(是的,三个字母的单词,这只是一个例子-冷静)
答案返回为空白,黄色,绿色,你有一个三个字母的单词列表,你想使用正则表达式搜索?你会怎么做?
首先,你可以从第三个位置的t开始:

[a-z]{2}t

我们可以通过注意到我们没有a来改进

[b-z]{2}t

我们可以进一步改进,说搜索必须有一个n。

(?=.*n)[b-z]{2}t

或将其分解;
(?=.*n)-向前看,并检查匹配中是否有n,在n之前可能有零个或多个字符
[b-z]{2} -在前两个位置中有两个字母,而不是“a”;
t -字面上是第三个位置的t

de90aj5v

de90aj5v4#

Grokking迅速环顾四周。
如何区分lookahead和lookbehind?跟我来个2分钟的旅行:

(?=) - positive lookahead
(?<=) - positive lookbehind

假设

A  B  C #in a line

现在,我们问B,你在哪里?
B有两种方法来声明它的位置:
第一,B前面有A,后面有C
第二,B在C的前面,在A的后面。
正如我们所看到的,在这两个解决方案中,后面和前面是相反的。
Regex是解决方案二。

4zcjmb1e

4zcjmb1e5#

我使用look behind查找模式,使用look forward negative查找缺少的表(nolock)

expression="(?<=DB\.dbo\.)\w+\s+\w+\s+(?!with\(nolock\))"

matches=re.findall(expression,sql)
for match in matches:
    print(match)

相关问题