看看背后:正则表达式中的风靡一时?

ber*_*roe 8 regex lookaround regex-lookarounds

最近的许多正则表达式问题在查询中都有某种环视元素,对我来说并不是匹配成功所必需的.是否有一些教学资源正在推广它们?我试图找出哪种情况下你会更好地使用积极的前瞻/后退.我可以看到的主要应用是在尝试匹配元素时.但是,例如,来自最近问题的这个查询有一个简单的解决方案来捕获.*,但为什么要使用后面的外观?

(?<=<td><a href="\/xxx\.html\?n=[0-9]{0, 5}">).*(?=<\/a><span
Run Code Online (Sandbox Code Playgroud)

而这个来自另一个问题:

$url = "www.example.com/id/1234";
preg_match("/\d+(?<=id\/[\d])/",$url,$matches);
Run Code Online (Sandbox Code Playgroud)

什么时候使用积极的环顾四周真的更好?你能举一些例子吗?

我意识到这与基于意见的问题接近,但我认为答案真的很有启发性.正则表达式令人困惑,没有让事情变得更复杂......我已经阅读了这个页面,并且对于何时使用它们而不是它们如何工作的一些简单指南更感兴趣.


感谢所有的答复.除了以下那些,我建议在这里查看m.buettner的好答案.

nne*_*neo 8

  1. 您可以捕捉重叠的匹配,并且您可以找到可能位于其他匹配的外观中的匹配.
  2. 您可以表达关于匹配的复杂逻辑断言(因为许多引擎允许您使用多个 lookbehind/lookahead断言,所有这些断言都必须匹配才能使匹配成功).
  3. Lookaround是表达公共约束的自然方式"匹配X,如果它后跟/前面是Y".(可以说)添加额外的"匹配"部分是不太自然的,这些部分必须通过后处理抛出.

当然,否定的外观断言甚至更有用.结合#2,它们可以让你做一些漂亮的向导技巧,甚至可能很难在通常的程序逻辑中表达.


例如,受欢迎的要求:

  • 重叠匹配:假设您想要找到给定基因序列中的所有候选基因.基因通常以ATG开始,以TAG,TAA或TGA结束.但是,候选人可能会重叠:可能存在错误的开始.所以,你可以使用这样的正则表达式:

    ATG(?=((?:...)*(?:TAG|TAA|TGA)))
    
    Run Code Online (Sandbox Code Playgroud)

    这个简单的正则表达式寻找ATG起始密码子,然后是一些密码子,然后是终止密码子.它可以提取看起来像基因的所有内容(没有开始密码子),并且即使它们重叠也能正确输出基因.

  • 零宽度匹配:假设您希望tr在计算机生成的HTML页面中找到具有特定类的每个.你可能会这样做:

    <tr class="TableRow">.*?</tr>(?=<tr class="TableRow">|</table>)
    
    Run Code Online (Sandbox Code Playgroud)

    这涉及</tr>行中出现裸露的情况.(当然,一般来说,HTML解析器是更好的选择,但有时你只需要快速而又脏的东西).

  • 多个约束:假设您有一个包含数据的文件id:tag1,tag2,tag3,tag4,其中包含任何顺序的标记,并且您希望查找标记为"green"和"egg"的所有行.这可以通过两个前瞻轻松完成:

    (.*):(?=.*\bgreen\b)(?=.*\begg\b)
    
    Run Code Online (Sandbox Code Playgroud)