3

我正在学习正则表达式,我发现了以下模式:

q(?=u)i

如果我尝试 math quit,它会失败,因为 q 匹配 q,u 匹配 u(所以前瞻是有效的),但是然后正则表达式在单词中回溯quit并且字符 u 再次比较,这次是 i。比赛失败。

我没有看到任何与此模式匹配的单词。有没有案例?或者这种结构(模式 - 前瞻 - 模式的其余部分)有用吗?

4

4 回答 4

3

正则表达式环视语法为零宽度

这意味着它匹配但不移动光标,因此在您的模式中:

  • q匹配“q”光标移动到“u”
  • (?=u)匹配 "u" 光标停留在 "u"
  • i与“u”不匹配,因此模式失败。

请注意,模式不会回溯,环视断言是零宽度。

如果您想匹配包含一系列字母中的“至少一个 X”的模式,该结构非常有用。例如:

[a-z]{4}[1-9]{3}(?=.*X)[a-zA-Z]{5}

表示四个小写字母后跟三个数字,后跟五个字母,任何大小写至少有一个“X”。

于 2013-08-28T08:09:23.983 回答
2

不,没有与您提到的我见过的类似的匹配模式,但是可以使用这样的结构(尽管承认有点奇怪),例如:

q(?=.*t)u

这个正则表达式将匹配任何以开头qu但后面有t某个地方的字符串。这意味着question,quit将匹配,但不匹配quasar。在这种情况下,可以使用等效且更易读的 (imo) 正则表达式qu(?=.*t)

于 2013-08-28T08:08:17.773 回答
1

我会说,如果先行 ( (?=...)) 之后(或之前)的模式是固定的。正则表达式并没有多大意义。喜欢:

foo(?=bar)fixed

但如果这fixed部分是动态的,那将很有用。看这个例子:

kent$  echo "fooququuuxxxxxxx"|grep -Po 'q(?=uu).*' 
quuuxxxxxxx

kent$  echo "fooququuuxxxxxxx"|grep -Po 'q(?=u).*' 
ququuuxxxxxxx

在上面的例子中,只有前瞻不同,你得到不同的匹配结果。

于 2013-08-28T08:19:45.777 回答
0

在应用这个问题中提出的用例结构和蜘蛛鲍里斯的回答时,我想出了这个解决方案

$detail = '[code]<!doctype>
<html>
  <head></head>
  <body><p>My Regex script</p></body>
</html>[/code]';

function regex($detail) 
{
   if(preg_match('#^\[code](?=.*(<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\2>))\[/code]#si',  $detail))
   {
       return true;
   }
   return false;        
}
echo regex($detail);

看看正则表达式引擎内部,这就是正在发生的事情。在申请^\[q](?=.*(<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\2>))[/q]*上述 $detail 时;\[q]匹配[q]并且代码的 html 部分匹配(<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\2>))

来自前瞻的匹配被丢弃,因此引擎从字符串中的 [/q] 退回到代码的 html 部分。前瞻成功,因此引擎继续运行[/q]。但[/q]不能匹配(<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\2>))。所以这个匹配尝试失败了。

但是,此正则表达式合成器有效:

#^\[code](?=.*(<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\2>\[/code]))#si

正则表达式引擎简单地说:“开始[code]标记后跟任何字符,然后是一对 html 标记,最后至少有一个结束[/code]标记”。

我希望这有助于更多地解释用例模式匹配(退出)。

于 2014-10-29T08:30:25.743 回答