对lookarounds的概念有一些问题

时间:2013-05-26 20:07:17

标签: regex regex-negation regex-lookarounds

我正在学习正则表达式并正在尝试环视,但我对这些表达式的放置顺序很困惑,就像我正在尝试以下

 b(?!a)

以上应该是b not followed by a。如果我把它放在那就好了

 (?!a)b

这匹配b无论来自哪里..

现在,如果我做这样的事情

    ^(?!.*\bMy Links\b).*$

在上面,负向前瞻是在消耗字符的字符串之前..现在为什么是

所以放置负前瞻的规则是什么?没有讨论整个模式中的位置。请解释一下吗?

2 个答案:

答案 0 :(得分:1)

我将使用插入符^来表示正在搜索的字符串和正则表达式中的当前搜索位置。使用正则表达式b(?!a),并假设我搜索cafebabe。系统首先尝试查找b。前四个字母失败,它到达第一个b

cafe^babe    ^b(?!a)

b匹配,因此它在正则表达式中继续:

cafeb^abe    b^(?!a)

但负面的前瞻失败;下一个字符是a。因此,正则表达式重置,我们转到字符串中的下一个位置:

cafeb^abe    ^b(?!a)

此操作失败,并继续

cafeba^be    ^b(?!a)

b匹配,所以

cafebab^e    b^(?!a)

并且字符串传递负向前瞻,因此我们到达:

cafebab^e    b(?!a)^

我们通过了。

现在,使用你的第二个表达式。记住,这是消极的前瞻,而不是消极的后视。

^cafebabe    ^(?!a)b

c通过,所以继续

^cafebabe    (?!a)^b

失败了。

重置正则表达式并推进字符串给出:

c^afebabe    ^(?!a)b

因为负前瞻失败而失败。

接下来两次失败就像第一次失败一样,留下:

cafe^babe    ^(?!a)b

负面前瞻成功,所以我们继续

cafe^babe    (?!a)^b

成功。假设你走得更远。下一封信失败了,正如第二封信所做的那样:

cafeb^abe    ^(?!a)b

之后

cafeba^be    ^(?!a)b

在当前位置之前的那个根本不重要。 b满足前面的负面看,所以我们去

cafeba^be    (?!a)^b

这就过去了。最后的选择失败了。

在第三个示例中,负向前瞻是在最开始,但以.*开头。因此,如果没有任何字符序列后跟一个单词边界,则后面跟着My Links后跟一个单词边界。如果通过,则继续使用整个字符串而不捕获任何内容。所以,它相当于这个字符串是否包含My Links被字边界包围?只需尝试查找\bMy Links\b并失败就会稍快一些。

答案 1 :(得分:1)

您必须知道,^$\b的外观为“零宽度”,这意味着它只代表光标位置 “字符”。在环视机制中,只需通过在进入环视部分之前使正则表达式引擎记住光标位置,然后将部分光标重置为之前记忆的位置即可完成。

现在,如果您想检查某个字母(在您的情况下为b)是否没有其他字母(在您的情况下为a),则需要将其写为b(?!a)。这将使正则表达式首先找到b(将在b之后设置光标),然后在a之后测试字母。

如果你将(?!a)b正则表达式写成每个光标位置(假设它在b之前)将进行前瞻测试(因此它会暂时将光标移动到下一个位置,读取在它之前的字符并检查它是否不是a。由于光标在b之前,它将接受b不是a并将光标移回{{1}之前现在在预测之后,测试正则表达式引擎将移动到tegex模式的下一部分(它将检查下一个字符是否为b),并且因为光标在b匹配之前将被找到。

因此,如果b (?!a)b每个b都可以,那么b无法a

相关问题