(?=) - positive lookahead
(?!) - negative lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind
(?>) - atomic group
(?=) - positive lookahead
(?!) - negative lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind
(?>) - atomic group
给定字符串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
(?>)
原子组会在组内第一个匹配项后退出组并忽略剩余的备选模式 (回溯被禁用)。
(?>foo|foot)s
应用于字符串 foots
时,将匹配第一个备选模式 foo
,因为后面不是字母 s
而失败,回溯被禁用,故只返回这个结果。非原子组会允许回溯;如果随后的匹配失败,它将回溯并使用备选模式,直到找到整个表达式的匹配或所有可能性都被耗尽。
(foo|foot)s
应用于字符串 foots
时,将:
foo
,因为后面不是字母 s
而失败,继而回溯至第二个备选模式;foot
,因为后面是字母 s
而成功,故只返回这个结果。(?>...)
的形式表示。当我们在表达式中使用括号时,这会创建一个捕获组,其中包含被括号包围的模式。 捕获组可以稍后在表达式中引用,并且还可以将其用作反向引用,并将其保留为匹配中的单独部分。 但是,如果我们只是需要一个分组而不需要捕获组,那么这个组可能会影响性能并导致回溯问题。原子组解决了这个问题。 它类似于普通的分组,但在匹配失败时它会防止回溯。 这意味着,在匹配失败时,原子组将保持匹配失败状态,而不是尝试回溯并寻找其他匹配。原子组非常适合处理长字符串和复杂模式,因为它们可以提高效率并避免回溯问题。 - Peter Krauss预测先行断言是零宽度断言,用于检查当前位置之后(或之前,基于正向或反向)是否存在一个正则表达式,当找到匹配时成功或失败(基于是否为正定向),并丢弃已匹配的部分。它们不会消耗任何字符 - 与其后面(如果有)的正则表达式匹配将从同一光标位置开始。
更多详细信息请阅读 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_1相同。现在,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_
后顾类似于前瞻:它只是查看当前光标位置之前的内容。一些正则表达式语言(例如JavaScript)不支持后顾断言。大多数支持后顾的语言(如PHP、Python等)要求后顾部分具有固定的长度。
REGEX_2
在 REGEX_1
后面时,(?=REGEX_1)REGEX_2
才匹配吗? - aandis为什么 - 假设你正在玩Wordle,输入了“ant”。(是的三字母词,只是举个例子-冷静点)
答案返回为空白、黄色和绿色,你有一个三字母词列表想要使用正则表达式进行搜索,你会怎么做呢?
首先,你可以从第三个位置的t的存在开始:
[a-z]{2}t
[b-z]{2}t
(?=.*n)[b-z]{2}t
或者来分解一下;
(?=.*n) - 向前查找,并检查匹配项中是否有一个n,它可能在n之前有零个或多个字符
[b-z]{2} - 在前两个位置上除了'a'以外的两个字母;
t - 第三个位置上确切地是一个't'
(?=) - positive lookahead
(?<=) - positive lookbehind
假设
A B C #in a line
现在,我们问B,你在哪里?
B有两种方法来声明它的位置:
一、B在A前面,C在后面
二、B在C前面(向前看),A在后面(向后看)。
可以看出,在这两个解决方案中,“前面”和“后面”是相反的。
正则表达式是第二种解决方案。
B
在A
前面,B
在C
后面。或者,C
在B
前面,A
在B
后面。难道我错过了什么吗? - Jon Grah我使用了“向后查找”来查找模式,并使用“向前负查找”来查找缺失的表(使用nolock)
expression="(?<=DB\.dbo\.)\w+\s+\w+\s+(?!with\(nolock\))"
matches=re.findall(expression,sql)
for match in matches:
print(match)