1

这很简单,我不明白为什么以下匹配:

preg_match('/\<td valign="top" class="bericht"\>(.*\s)*<\/td>/',$html,$matches3);

而这个没有:

preg_match('/\<td valign="top" class="bericht"\>(.*(\s)?)*<\/td>/',$html,$matches3);

我想 ?表示零或一。所以我不明白这怎么会使某些东西不匹配。

使用 RegexPal ( http://regexpal.com/ ) 进行测试时,一切都按预期工作。所以第二个确实匹配。

4

2 回答 2

2

除了蒂姆·皮茨克所说的。. .

您如何确定第二个不匹配?请注意,第一个模式将设置$matches3[1]为表格单元格的内容,而第二个模式将始终设置$matches3[1]为空字符串。

假设$html看起来像这样:

<td valign="top" class="bericht">yes </td>

然后(.*\s)*第一个模式中的 将匹配yes ,之后不再匹配,因此它将存储yes $matches3[1].

但是(.*(\s)?)*第二个模式中的 将匹配yes ,然后是空字符串,因此它将空字符串存储在$matches3[1].

我不确定您到底要做什么,但是如果您的目标只是捕获 and 之间的所有内容<td valign="top" class="bericht"></td>无论那可能是什么,那么您应该编写:

preg_match('/\<td valign="top" class="bericht"\>(.*?)<\/td>/s',$html,$matches3);

(其中*?意思是“零次或多次,但最好尽可能少,/s意思是“允许.匹配任何字符,甚至是换行符”)。

于 2012-06-22T14:46:50.040 回答
1

这两个应该匹配。但是第二个可能会遇到灾难性的回溯,因为

  • .也匹配\s(除了,这是踢球者,换行符)
  • 它使用嵌套的无限量词(本质上,这是(.*)*因为\s是可选的)

因此,给定足够大的输入和足够的换行符,PHP 将在超过某个回溯阈值后停止匹配(您可以在某处配置,但我忘记了在哪里),而在线正则表达式测试器可能会继续并耗尽所有可能的排列。

于 2012-06-22T14:42:05.197 回答