【问题标题】:PHP preg_match_all search in preg_match_all (2 times)PHP preg_match_all 在 preg_match_all 中搜索(2 次)
【发布时间】:2016-11-21 12:46:26
【问题描述】:

我的英语不好。

我正在尝试在 preg_match 中进行 preg_match!

我知道了:

if( preg_match_all('~<td class="fluctuation">\s*(.*?)\s*</td>~si', $input, $item_updown_select ) );

如果我 var_dump 它,我会得到:

array(2) {
  [0]=>
  array(32) {
    [0]=>
    string(153) "<td class="fluctuation">
                    <span class="down"><span class="icon"></span>13.31%</span>
                </td>"
    [1]=>
    string(150) "<td class="fluctuation">
                    <span class="up"><span class="icon"></span>3.45%</span>
                </td>"
    [2]=>
    string(150) "<td class="fluctuation">
                    <span class="up"><span class="icon"></span>4.56%</span>
                </td>"
    [3]=>
    string(151) "<td class="fluctuation">
                    <span class="up"><span class="icon"></span>10.07%</span>
                </td>"

}
  [1]=>
  array(32) {
    [0]=>
    string(58) "<span class="down"><span class="icon"></span>13.31%</span>"
    [1]=>
    string(55) "<span class="up"><span class="icon"></span>3.45%</span>"
    [2]=>
    string(55) "<span class="up"><span class="icon"></span>4.56%</span>"
    [3]=>
    string(56) "<span class="up"><span class="icon"></span>10.07%</span>"
  }
}

现在我只想要这个数组中的类!

如果我这样做,我知道它会起作用:

if( preg_match_all('~<span class="\s*(.*?)\s*"><span class~si', $item_updown_select[1][0], $item_updown0 ) );
if( preg_match_all('~<span class="\s*(.*?)\s*"><span class~si', $item_updown_select[1][1], $item_updown1 ) );
if( preg_match_all('~<span class="\s*(.*?)\s*"><span class~si', $item_updown_select[1][2], $item_updown2 ) );
if( preg_match_all('~<span class="\s*(.*?)\s*"><span class~si', $item_updown_select[1][3], $item_updown3 ) );

但如果我得到了超过 3 个项目,那就是糟糕的编码!

你知道更好的方法吗?

我现在用谷歌搜索了大约 8 个小时,但没有想到。

我已经尝试过 foreach:

foreach($item_updown_select[1] as $index => $text_to_draw) {
    if( preg_match_all('~<span class="\s*(.*?)\s*"><span class~si', $text_to_draw, $item_updown ) );
    print_r( $item_updown );
}

这就是我的输出:

Array
(
    [0] => Array
        (
            [0] => <span class="down"><span class
        )

    [1] => Array
        (
            [0] => down
        )

)
Array
(
    [0] => Array
        (
            [0] => <span class="up"><span class
        )

    [1] => Array
        (
            [0] => up
        )

)
Array
(
    [0] => Array
        (
            [0] => <span class="down"><span class
        )

    [1] => Array
        (
            [0] => down
        )

)

我在 foreach 上的问题是:我现在如何分别显示每个数组?

我不知道 foreach 是否是正确的方法。

希望你理解我,知道我想要什么。

希望你能帮助我!!

【问题讨论】:

  • @deceze 你是什么意思?
  • 你应该使用preg_replace_callback('*pattern*', array('Someclass','SomeMethodWhichDoesYourThing'), $content_to_search)
  • 好的,直截了当:不要使用正则表达式解析 HTML。使用 HTML 解析器解析 HTML。可能使用正则表达式解析 HTML,但它不必要地复杂和脆弱。如果您想编写健全、可维护的代码,请使用 HTML 解析器。

标签: php foreach preg-match-all


【解决方案1】:

通常,我建议不要使用正则表达式来解析 HTML,as noted in a previous reply

但是,对于这种相当有限的用途,我认为您可能会侥幸成功。请注意,如果底层 HTML 发生变化,或者与上面的示例不同,这将不起作用(不再)

// If you _only_ need the class:
$pattern = '~<td class="fluctuation">\s*<span class="([^"]+).*?</td>~si';

// If you need the class as well:
$pattern = '~<td class="fluctuation">\s*(<span class="([^"]+).*?)\s*</td>~si';

if( preg_match_all($pattern, $input, $item_updown_select ) );

第一个 RegEx 将只为您提供 $matches[1] 类,而第二个将为您提供 $matches[2] 中的类。

最后我强烈建议学习DOMdocument,因为它使使用 HTML 变得更容易,并且更能容忍变化。你可以从following tutorial开始。

【讨论】:

  • 现在我只得到 13.31% 这样的百分比?
  • 在这种情况下,源材料要么与您在上面发布的示例不同,要么您做错了什么。正则表达式的工作方式与指定的一样,如下所示:regexpal.com/?fam=96280
  • 你的只给我上课?我不明白:/
  • 是的,第一个模式只会给你类。
【解决方案2】:

使用 DOMDocument 解析 HTML:

$html = <<<EOD
  <table>
    <tr>
      <td class="fluctuation">
        <span class="down"><span class="icon"></span>13.31%</span>
      </td>
      <td class="fluctuation">
        <span class="up"><span class="icon"></span>3.45%</span>
      </td>
      <td class="fluctuation">
        <span class="up"><span class="icon"></span>4.56%</span>
      </td>
      <td class="fluctuation">
        <span class="up"><span class="icon"></span>10.07%</span>
      </td>
    </tr>
  </table>
EOD;

$dom = new DOMDocument();
$dom->loadHTML($html);
$finder = new DomXPath($dom);
$nodes = $finder->query("//td[@class='fluctuation']");

$classes = array();
foreach($nodes as $node) {
    foreach($finder->query("span", $node) as $span) {
        $class = $span->getAttribute('class');
        $classes[] = $class;
    }

}
print_r($classes);

输出:

Array
(
    [0] => down
    [1] => up
    [2] => up
    [3] => up
)

【讨论】:

    猜你喜欢
    • 2014-09-19
    • 2014-05-27
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 2013-07-17
    • 2015-06-24
    相关资源
    最近更新 更多