我现在比一年前聪明得多,所以我完全放弃了我最初的建议。尝试解析有效 html 时最好/最可靠的方法是使用 dom 解析器。 XPath 使寻找节点/元素变得超级容易。一旦您取消了不包含 Part Number 关键字的 <p> 标记,正则表达式模式仍然是合适的工具。
代码:(Demo)
$html = <<<HTML
<p>Zip Code: 99501</p>
<p>Part Number: 67001</p>
<p>Part Number: 98765 - 10000kg capacity</p>
<p>Some dummy/interfering text. Part Number: 12345</p>
<p>Zip Codes: 99501, 99524 , 85001 and 72201</p>
<p>Part Number: 50545 – 450g Cartridge 50525 - 2.5kg Tub 50520 - 20kg Pail 50555 - 55kg Drum 50575 *Indent - 175kg Drum</p>
HTML;
$partnos = [];
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//p[starts-with(., 'Part Number: ')]") as $node) {
// echo "Qualifying text: {$node->nodeValue}\n";
if (preg_match_all('~\b\d{5}\b~', $node->nodeValue, $matches)) {
$partnos = array_merge($partnos, $matches[0]); //or array_push($partnos, ...$matches[0]);
}
}
var_export($partnos);
输出:
array (
0 => '67001',
1 => '98765',
2 => '50545',
3 => '50525',
4 => '50520',
5 => '50555',
6 => '50575',
)
xpath 查询说:
//p #find p tags at any level/position in the dom
[starts-with(. #with a substring at the start of the node's text
, 'Part Number: ')] #that literally matches "Part Number: "
正则表达式模式使用word boundary metacharacters (\b) 来区分部件号和非部件号。如果您因为问题中未包含某些数据而需要调整模式,请告诉我,我会提供进一步的指导。
最后,我确实使用了一个纯正则表达式解决方案,该解决方案将\G 合并到Part Number: 或之前的匹配之后“继续”匹配,但是这种类型的模式有点难以概念化,并且再次使用 dom 解析器在处理有效 html 时,它是一种比正则表达式更稳定的工具。