我有以下HTML代码:
<span role="button" class="a-n S1xjN" tabindex="0">414,817 people</span>
如何使用preg_match
函数获取414817
号码?
答案 0 :(得分:6)
正则表达式是错误的工具。 HTML为not a regular language,无法使用正则表达式进行准确解析。请改用DOM解析器。它不仅更容易,更准确,更可靠,并且在将来标记格式发生变化时不会中断。
这是使用PHP的内置DOMDocument类在<span>
标记内获取内容的方法:
$dom = new DOMDocument;
$dom->loadHTML($yourHTMLString);
$result = $dom->getElementsByTagName('span')->item(0)->nodeValue;
如果有多个标签,并且您想要从所有标签中获取节点值,则可以使用foreach
循环,如下所示:
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('span') as $tag) {
echo $tag->nodeValue . '<br/>';
}
最后,要从节点值中仅提取数字,您有以下几种选择:
// Split on space, and get first part
echo explode(' ', $result, 2)[0];
// Replace everything that is not a digit or comma
echo preg_replace('/[^\d,]/', '', $result);
// Get everything before the first space
echo strstr($result, ' ', 1);
// Remove everything after the first space
echo strtok($result, ' ');
所有这些陈述都会输出414,817
。有大量string functions可供您使用,您可以选择一种适合您需求的解决方案。
如果您绝对必须使用preg_match()
,那么您可以使用以下内容:
if (preg_match('#<span[^<>]*>([\d,]+).*?</span>#', $result, $matches)) {
echo $matches[1];
}
[^<>]*
表示“匹配任意数量的字符,但有角度的括号”,确保我们不会意外地突破我们所处的标记。
.*?
(注意?
)表示“匹配任意数量的字符,但只能尽可能少”。这样可以避免匹配标记中的第一个<span>
标记(如果有多个<span>
)。
我绝对不能保证正则表达式始终工作,但对于想要完成一次性工作的人来说应该足够了。在这种情况下,最好是使用正则表达式来处理理智的事情,而不是为不普遍完美的事情而哭泣:)