php和regex:如何捕获多行并在第一次出现时停止?

时间:2015-03-02 11:43:42

标签: php regex preg-match

我希望捕获<td id="adress"></td>之间的所有内容:

<td id="adress">
   hello<br>
   world<br>
   line3<br>
</td>
<td id="adress2">
   hello2<br>
   world2<br>
   line3<br>
</td>

这意味着:多线捕获并在第一次出现时停止 所以结果应该是:

   hello<br>
   world<br>
   line3<br>

有任何线索吗?

我尝试过:

preg_match_all("/<td id=\"AddressHolder\">.*<\/td>/s", $source, $output_array);

但这不会在最初</td>停止。

2 个答案:

答案 0 :(得分:1)

如果您希望正则表达式引擎在第一次出现后停止,则需要使用preg_match函数而不是preg_match_all

$st = <<<EOT
<td id="adress">
   hello<br>
   world<br>
   line3<br>
</td>
<td id="adress2">
   hello2<br>
   world2<br>
   line3<br>
</td>
EOT;
preg_match('~<td id="adress[^"]*">[^\n]*\n\K.*?(?=\n[^\n]*<\/td>)~s', $st, $match);
print_r($match[0]);

<强>输出:

   hello<br>
   world<br>
   line3<br>

答案 1 :(得分:1)

如果您在.*之后添加问号,则匹配将在第一次出现时停止,例如</td>。您也不必使用preg_match_all

$source = <<<EOS
<td id="adress">
   hello<br>
   world<br>
   line3<br>
</td>
<td id="adress2">
   hello2<br>
   world2<br>
   line3<br>
</td>
EOS;

preg_match("/<td id=\"adress\">(.*?)<\/td>/s", $source, $matches);
$address = $matches[1];

print_r($address);

输出:

hello<br>
world<br>
line3<br>