【问题标题】:Struggling to match a string using preg_match_all()努力使用 preg_match_all() 匹配字符串
【发布时间】:2015-09-26 15:00:25
【问题描述】:

我正在寻找这个:

<h1> sample string 123.456 - find me </h1>

请注意我感兴趣的 h1 标签之间的内容。另请注意,字符串是包含数字、字母和/或字符的任意组合的变量。因此,还需要使用相同的 preg_match_all 搜索在 h1 标签之间找到以下内容:

<h1>there are no numbers this time</h1>

或

<h1>this one may be tricky ?!-.</h1>

我现在尝试了以下方法:

preg_match_all("/<h1>[\w\d\D\s]+?<\/h1>$/siU", $input, $matches);
print_r($matches);

脚本运行...但是当我print_r() 时,$matches 数组不包含任何值。因此它看起来像这样 'Array ( [0] => Array ( ) ) '

【问题讨论】:

  • \s 代表空格而不是字母数字字符。即使有良好的课程"\z " 也能够使世界上的所有模式都失败,因为字符串末尾没有字符。
  • ^ 是字符串的开头。如果您的字符串只有&lt;h1&gt;...,则将正则表达式中的h1 更正为&lt;。 s 修饰符也是. 匹配多行以及您的正则表达式不使用.。
  • 感谢您的及时回复。因此,如果我将以上内容编辑为: "/^(

    )[\w]*/siU" ?

  • 如果你想要h1标签的内容,你考虑过解析器吗?
  • 我认为解析器最适合你。如果你只是想用这个来学习正则表达式,那么我建议你在一个解释每一位正在做什么的网站上尝试你的正则表达式。像 regex101.com 这样的东西。您的[\w\d\D\s]+? 等同于.+?。你的\d\D 说什么,因为你允许数字和任何非数字。 \w 还包括数字。

标签: php preg-match-all


【解决方案1】:

使用解析器可能是您的最佳选择。您的问题/cmets 不清楚,并且与您要确定的内容相矛盾。

$doc = new DOMDocument();
libxml_use_internal_errors(true);
$html = '<h1>Hi</h1><h2>test</h2><strong>Test</strong><h1>More</h1>';
$doc->loadHTML($html);
libxml_use_internal_errors(false);
$h1s = $doc->getElementsByTagName('h1');
foreach ($h1s as $h1) {
    echo $h1->nodeValue . "\n";
}

然后您可以在nodeValue 上使用正则表达式来确认该值是否符合预期。

输出:

Hi
More

您最初的问题可能是一个正则表达式..

<h1>[a-zA-Z\d]+?<\/h1>

演示:https://regex101.com/r/lD5wQ3/1

【讨论】:

  • 嗨 - 我从来没有考虑过这样做。我的问题:它是比 preg_match_all 更快的方法吗?同样,这种方法会被认为是更好的做法吗?说你搜索 4,000 页是为了争论?
  • 我认为这是一种比使用正则表达式更好、更安全的方法。我没有进行基准测试,所以我不能说效率是/不是。
  • 最后使用了解析器。出于某种原因... pre_match_all 没有选择 h1 标签。
【解决方案2】:

问题是,预期的结果是什么? 你可以试试这个:

$input = '<h1> Alphanumeric value here </h1>';
preg_match_all("/^<h1>(.*)<\/h1>/su", $input, $matches);
print_r($matches);

结果:

Array
(
    [0] => Array
        (
            [0] => <h1> Alphanumeric value here </h1>
        )

    [1] => Array
        (
            [0] =>  Alphanumeric value here 
        )

)

【讨论】:

  • 希望他在页面上没有超过 1 个h1。你的正则表达式是贪婪的,并且会继续下去。 regex101.com/r/lD5wQ3/3
【解决方案3】:
preg_match_all("%^<h1>[a-zA-Z0-9\s]*</h1>$%siU", $input, $matches);

这将返回&lt;h1&gt;标签内的文本,所以如果你想包含标签,只需这样做

"&lt;h1&gt;".$result."&lt;/h1&gt;"

【讨论】:

    【解决方案4】:

    下面获取所有三个字符串:

    <h1>\s?[a-z0-9\s?!.]*<\/h1> 
    

    【讨论】:

    • 不需要{1}。 09 不是一个范围。 \s 也是必需的 OP 仅表示字母数字。
    • 那么它应该写成:

      AlphanumericValueHere

    • 我尝试了上述方法并得到了类似的结果'Array ( [0] => Array ( ) ) '。有什么想法吗?
    • @fsn 字符串中有空格、数字、字母和可能的符号。
    • @GtDriver 使用预期的确切示例更新问题。如果没有,你只会得到猜测。
    猜你喜欢
    • 2022-01-19
    • 2021-12-19
    • 2021-10-09
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    相关资源
    最近更新 更多