首页 > 解决方案 > PHP preg_match_all 谜语

问题描述

我使用的是 PHP 5.6 版,但我无法弄清楚为什么正则表达式不能正确匹配第二行。

 $str = '<tr><td class="DH">Sale Date</td></tr><tr><td class="DD">10-MAR-15</td></tr><tr><td class="DD">18-APR-17</td></tr>';

 preg_match_all('/<tr>.*?class="D.*?<\/tr>/', $str, $matches);
 print_r($matches);

 preg_match_all('/<tr>.*?class="DH.*?<\/tr>/', $str, $matches);
 print_r($matches);

 preg_match_all('/<tr>.*?class="DD.*?<\/tr>/', $str, $matches);
 print_r($matches);

此代码输出:

Array
(
    [0] => Array
        (
            [0] => <tr><td class="DH">Sale Date</td></tr>
            [1] => <tr><td class="DD">10-MAR-15</td></tr>
            [2] => <tr><td class="DD">18-APR-17</td></tr>
        )

)
Array
(
    [0] => Array
        (
            [0] => <tr><td class="DH">Sale Date</td></tr>
        )

)
Array
(
    [0] => Array
        (
            [0] => <tr><td class="DH">Sale Date</td></tr><tr><td class="DD">10-MAR-15</td></tr>
            [1] => <tr><td class="DD">18-APR-17</td></tr>
        )

)

<tr>正则表达式本质上意味着匹配和之间</tr>包含的所有最短序列 class="D

注意第一个正则表达式如何分别正确匹配所有 3 行。

第二个执行相同的操作,但希望该行包含class="DH它正确执行的操作。

第三个正则表达式应该匹配包含class="DD. 由于某种原因,只有第一个结果(对应于第二个表行)想要包括前一行。

即使我在</tr>和之间添加一个空格<tr>,我也会</tr> <tr>得到相同的结果。但是,如果我插入换行符,事情就会起作用。

谁能解释发生了什么以及如何修复我的代码?

标签: phpregexpreg-match-all

解决方案


/<tr>.*?class="DD.*?/

说“找到<tr>,然后匹配所有内容,直到找到class="DD"。所以它看到:

<tr><td class="DH">Sale Date</td></tr><tr><td class="DD">

并匹配第一个<tr>,然后是.*匹配项<td class="DH">Sale Date</td></tr><tr><td,然后查看class="DH"哪个匹配下一部分。

当您添加换行符时,.*停止匹配,因此它可以工作。


推荐阅读