Regex 向后看:雷格克斯的风靡一时?
最近,许多正则表达式问题在查询中都有一些环顾四周的元素,在我看来,这对比赛的成功不是必需的。是否有一些教学资源在推广它们?我正试图找出哪种情况下,你最好采用积极的前瞻性/前瞻性。我看到的主要应用程序是在尝试不匹配元素时。但是,例如,这个来自最近一个问题的查询有一个简单的解决方案来捕获Regex 向后看:雷格克斯的风靡一时?,regex,regex-lookarounds,lookaround,Regex,Regex Lookarounds,Lookaround,最近,许多正则表达式问题在查询中都有一些环顾四周的元素,在我看来,这对比赛的成功不是必需的。是否有一些教学资源在推广它们?我正试图找出哪种情况下,你最好采用积极的前瞻性/前瞻性。我看到的主要应用程序是在尝试不匹配元素时。但是,例如,这个来自最近一个问题的查询有一个简单的解决方案来捕获*,但是为什么要使用look back (?<=<td><a href="\/xxx\.html\?n=[0-9]{0, 5}">).*(?=<\/a><span (
*
,但是为什么要使用look back
(?<=<td><a href="\/xxx\.html\?n=[0-9]{0, 5}">).*(?=<\/a><span
(?<=<td><a href="\/xxx\.html\?n=[0-9]{0, 5}">).*(?=<\/a><span
(?
您可以捕获重叠的匹配,并且可以找到可能位于其他匹配的查找区域中的匹配
您可以表达有关匹配的复杂逻辑断言(因为许多引擎允许您使用多个lookback/lookahead断言,所有这些断言都必须匹配才能成功匹配)
Lookaround是一种表达公共约束“匹配X,如果后面跟/前面跟Y”的自然方式。添加额外的“匹配”部分(可以说)不太自然,这些部分必须通过后处理丢弃
当然,负面环视断言更有用。与#2结合使用,它们可以让您完成一些漂亮的向导技巧,这在通常的程序逻辑中甚至很难表达
例如,根据大众要求:
- 重叠匹配:假设您希望找到给定基因序列中的所有候选基因。基因通常以ATG开头,以TAG、TAA或TGA结尾。但是,候选基因可能重叠:可能存在错误开始。因此,您可以使用如下正则表达式:
ATG(?=((?:...)*(?:TAG|TAA|TGA)))
<tr class="TableRow">.*?</tr>(?=<tr class="TableRow">|</table>)
#ff00fffirstword#445533secondword##008877thi#rdword#
这个简单的正则表达式寻找ATG起始密码子,然后是一些密码子,然后是一个终止密码子。它提取所有看起来像基因的东西(无起始密码子),并正确地输出基因,即使它们重叠
- 零宽度匹配:假设您希望在计算机生成的HTML页面中查找每个具有特定类的
tr
ATG(?=((?:...)*(?:TAG|TAA|TGA)))
<tr class="TableRow">.*?</tr>(?=<tr class="TableRow">|</table>)
#ff00fffirstword#445533secondword##008877thi#rdword#
有两件大事:
- 它们是零宽度断言。它们需要匹配,但不消耗任何输入字符串。这允许描述匹配结果中不包含的字符串部分。通过在环视表达式中使用捕获组,它们是多次捕获部分输入的唯一方法
- 它们简化了很多事情。它们很容易允许组合(相交)多个表达式以匹配字符串的同一部分
请记住,正/负环顾与正则表达式引擎相同。环顾的目标是在“正则表达式”中的某个位置执行检查
主要兴趣之一是在不使用捕获括号的情况下捕获某些内容(捕获整个模式),例如:
字符串:aaabbbccc
正则表达式:(?一个简单的例子是,当你将模式锚定到一行的开始或结束处,并且只想确保某个东西在你匹配的模式的正前方或正后方时,它们很方便。我试着解决你的问题:
- 在我看来,查询中的某种环顾元素对于匹配的成功不是必需的
当然,它们是匹配所必需的。只要环顾断言失败,就没有匹配。它们可用于确保模式周围的条件必须为真。整个正则表达式仅在以下情况下匹配:
- 该图案确实适合和
- lookaround断言是正确的
==>但是返回的匹配只是模式
- 什么时候用积极的眼光看待周围才是真正更好的
简单回答:当你想要东西在那里时,但你不想匹配它!
因为它们是零宽度断言,这意味着它们不匹配字符序列,它们只是确保它在那里。因此环顾表达式中的字符不是“已使用”的,正则表达式引擎在最后一个“已使用”字符之后继续
- 关于你的第一个例子:
(?<=<td><a href="\/xxx\.html\?n=[0-9]{0, 5}">).*(?=<\/a><span
很有趣。它正在匹配一个数字序列(\d+
),在该序列之后,lookback断言将检查是否有一个前面有“id/”的数字。这意味着如果有多个数字或文本“id/”将失败数字丢失之前。表示此正则表达式仅匹配一个数字,而之前有匹配文本
- 教学资源
我假设你了解环顾四周的良好用途,并询问为什么在没有明显理由的情况下使用环顾四周
我认为人们使用正则表达式的方式主要有四类:
验证
验证通常是在整个文本上进行的。不可能像您描述的那样进行环顾
匹配
提取部分文本。使用Lookarounds主要是因为开发人员懒惰:避免捕获。
例如,如果我们在设置文件中有一行Index=5
,我们可以匹配/^Index=(\d+)/
,并获得第一个组,或者匹配/(?环顾断言
也可以用于减少回溯,这可能是正则表达式中性能差的主要原因
例如:正则表达式^[0-9A-Z]([-.\w]*[0-9A-Z])*@
(1)也可以编写^[0-9A-Z][-.\w]*(?查找断言)
有关回溯的更多信息
我前一段时间打了这封信,但很忙(仍然很忙,所以我可能需要一段时间才能回复),没有抽出时间发布。如果你仍然愿意接受答案
是否有一些教学资源在推广它们
我不这么认为,这是绝对的
<td><a href="\/xxx\.html\?n=[0-9]{0,5}">(.*?)<\/a><span
\bdog\b(?=(?:[^"]*"[^"]*")*[^"]*$)
\bdog\b(?!(?:[^"]*"[^"]*")*[^"]*"[^"]*$)
(?:"[^"]+"[^"]+?)?(\bdog\b)
\bdog\b(?!(?:[^"]*"[^"]*")*[^"]*$)
\bdog\b(?=(?:[^"]*"[^"]*")*[^"]*"[^"]*$)
"[^"]*(\bdog\b)[^"]*"
"[^"]*?(\bdog\b)[^"]*?(?:(\bdog\b)[^"]*?)?"
abcdefghijkl
(?=(...))
1A Line1 Detail1 Detail2 Detail3 2A Line2 Detail 3A Line3 Detail Detail
1A Line1 Detail1 Detail2 Detail3
2A Line2 Detail
3A Line3 Detail Detail
[0-9]+A Line[0-9]+(?: \w+)+
[0-9]+A Line[0-9]+(?: \w+)+?
[0-9]+A Line[0-9]+(?: \w+)+?(?= [0-9]+A Line[0-9]+|$)
#ff00fffirstword#445533secondword##008877thi#rdword#
#ff00ff and firstword
#445533 and secondword#
#008877 and thi#rdword#
(#[0-9a-f]{6})(.+?)(?=#[0-9a-f]{6}|$)
^(?=[^0-9]*[0-9])(?=[^a-z]*[a-z])
##-#
#-##
^(?=.{4}$)\d+-\d+
(?=.*(\b\w{3}\b))(?=.*(\b\d{4}\b)).*
Oct-2013
2013-Oct
Oct-2013
Oct-2013
\G\d{1,2}\K\B(?=(?:\d{2})*\d{3}(?!\d))
this is a sentence
\s+
^\s*|\s$|\s+(?=\s)
(?<=[0-9])(?=[A-Z])