3 回答
一个简单的例子,你可能想要(?!xyz)
,但不是(?!xyz)(?<!xyz)
,是在正则表达式xyz(?!xyz)
中,以匹配xyz
不是紧跟在另一个后面的xyz
。只需尝试一下,xyz(?!xyz)(?<!xyz)
您就会发现它永远不会匹配:(?<!xyz)
检查的点总是在 之前xyz
,因为您只是匹配了它。
恐怕你没有抓住重点。
Look-behind 是在模式中的位置之前检查字符,look-ahead 是在之后检查字符。
abc(?!xyz)
检查是否abc
没有跟在后面xyz
,这是有道理的:see no match with abcxyzz
here )。
(?<!xyz)abc
将检查之前的字符abc
,并且有匹配项abcxyzz
(请参见此处)。
现在,在 中abc(?!xyz)(?<!xyz)
,(?<!xyz)
没有意义,因为它总是正确的(我们有abc
,不是xyz
)。abc(?!xyz)(?<!xyz)
= abc(?!xyz)
。
中(?!xyz)(?<!xyz)abc
,(?!xyz)
部分总是正确的,因为abc
不是xyz
。(?!xyz)(?<!xyz)abc
= (?<!xyz)abc
。
按照您建议的方式使用前瞻和后视是没有意义的,它只会增加开销并降低性能,不会带来统一,但会给引擎带来痛苦。
从理论上讲,很容易说:“好吧,让程序根据任何相邻文字的位置自动决定方向”,所以(?<!xyz)house
or.*(?<!xyz)house
和house(?!xyz)
orhouse(?!xyz).*
都是有意义的。规则是“如果文字在左侧,则使用前瞻运算符,而如果在右侧,则使用后瞻运算符。”。如果双方都是字面的,那么这个表达无论如何都是毫无价值的。这在大多数xyz
情况下都是有效的(尽管正如 hvd 所指出的,如果字符数与相邻文本中的字符重叠(例如:中的星号)重叠,则它将不起作用(?!xyz)xy*z
)。
但是,当双方都不是字面意思时,就会出现更多问题。
例如,尝试使用正则表达式:the ..(?!u).. house
针对文本“the blue house”。显然,?!
与此处的行为不同?<!
,可能需要任何一种选择。