【问题标题】:preg_match_all() in php does not show all resultsphp 中的 preg_match_all() 不显示所有结果
【发布时间】:2017-03-15 10:59:17
【问题描述】:

我正在尝试匹配每个 openingclose 自定义标记 <xyz></xyz> 以及它们嵌入在这些示例中的普通 html 标记中的位置:

$str =<<<'EOS'
      <xyz id="x464CaqYxUMjG7RJk4yXa8qY" data-arg="x=ktvBDojzvthKO9OOBzQLt6pi">
         <xyz id="x" data-html>
            <h2>Security, Comfort, &amp; Convenience</h2>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque dicta magni amet atque doloremque velit unde adipisci omnis hic quaerat.</p>
            <p><xyz id="z9Sjvxxop9BiQKc9HMzuk9Z8"></xyz></p>
         </xyz>
      </xyz>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
      <xyz id="ZQpXDHuJHILTVjlRpodO9WrT" data-arg="x=ktvBDojzvthKO9OOBzQLt6pi,y=IyL8raQqbQQM65w7bPWJLRSJ">
         <xyz id="x" data-html>
            <h2>Security, Comfort, &amp; Convenience</h2>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque dicta magni amet atque doloremque velit unde adipisci omnis hic quaerat.</p>
            <p><xyz id="z9Sjvxxop9BiQKc9HMzuk9Z8"></xyz></p>
         </xyz>
         <xyz id="IyL8raQqbQQM65w7bPWJLRSJ" data-html>
            <div class="text-center IyL8raQqbQQM65w7bPWJLRSJ">
               <h2>Happy Clients</h2>
               <p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. </p>
            </div>
         </xyz>
      </xyz>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
EOS;

我在 php 中使用这个正则表达式:

$tag = "/<xyz([^>]+)>|(<\\/xyz>)/imu";
$out = array();
$result = \preg_match_all($tag, $str, $out, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);

当我打印结果时:

echo nl2br("\n<pre>".\htmlspecialchars($str, ENT_NOQUOTES, ENCODING)."</pre>");
echo \nl2br(\print_r($out, true));
echo preg_last_error();

可以看到正在打印的子模式([^&gt;]+)

[1] => Array
(
[0] => Array
(
[0] => id="x464CaqYxUMjG7RJk4yXa8qY" data-arg="x=ktvBDojzvthKO9OOBzQLt6pi"
[1] => 10
)
...

NOT通常应该包含所有表达式的追赶的0-indeces:

Array
(
[0] => Array
(
[0] => Array
(
[0] => **where is the result???**
[1] => 6
)
...

知道我在这里做错了什么吗?

ps:我的正则表达式在https://regex101.com/http://regexr.com/ 等在线工具中通过单个反斜杠&lt;dil([^&gt;]+)&gt;|&lt;\/dil&gt;

【问题讨论】:

  • 按照哈桑的回答:echo \nl2br(\htmlspecialchars(\print_r($out, true), ENT_NOQUOTES, ENCODING));

标签: php regex pcre


【解决方案1】:

问题是您正在“打印” HTML 结果,而您的浏览器会自动解析它。

例如在 Firefox 中点击 CTRL+U 将显示页面源代码

是这样的:

如您所见,您的数据就在那里,

例如,尝试将结果打印在 textarea 中,如下所示:

foreach ($out[0] as $_out) {
    echo "<textarea>" . htmlspecialchars($_out[0]) . "</textarea><hr />";
}

你会正常得到结果。

这是另一个例子:https://3v4l.org/hk7Od

【讨论】:

  • 糟糕!太棒了!
【解决方案2】:

改用解析器的更好方法 (demo)。
例如。下面的 sn-p 打印出/xyz/xyz 下的每个标题(h2):

<?php
# your string over here

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($your_string_here, LIBXML_HTML_NOIMPLIED);

$xpath = new DOMXPath($dom);
libxml_clear_errors();

# adjust this xpath as needed
$headers = $xpath->query("//xyz/xyz/h2");
foreach ($headers as $header) {
    echo $header->textContent . "<br>";
}
?>

这里,唯一需要调整的是 xpath 查询。

【讨论】:

  • 问题是浏览器正在解析 HTML 输出,而不是在模式本身。
  • 有趣的方法。我会深入了解一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 2017-12-29
  • 2019-12-05
  • 1970-01-01
相关资源
最近更新 更多