繁体   English   中英

使用正则表达式模式重复捕获组

[英]Repeating capture group with a regex pattern

我正在尝试从网站上获取产品列表,包括各个产品代码。 产品代码是5位代码,元素的复杂程度从

<p>Part Number: 67001</p>

<p>Part Number: 50545 &ndash; 450g Cartridge 50525 - 2.5kg Tub 50520 - 20kg Pail 50555 - 55kg Drum 50575 *Indent - 175kg Drum</p>

不幸的是,五位数字模式遍及整个网页,所以我不能只使用/\\d{5}/

我使用的是正则表达式,该正则表达式仅提取“零件号”元素中的5位数字,而不提取网页的其余部分。

类似于: /\\<p\\>Part\\s*Number\\:\\s*((\\d{5}) repeat this capture group n times)\\<\\/p\\>/

我知道我可以做到这一点,可以分阶段分解页面并逐个应用一个正则表达式。 例如

第一阶段/\\<p\\>Part\\s*Number\\:\\s*.*?\\<\\/p\\>/
第二阶段/\\d{5}/

但是有可能以一种正则表达式模式执行吗?

我现在比一年前要聪明得多,所以我完全抹掉了最初的建议。 尝试解析有效​​的html时,最好/最可靠的方法是使用dom解析器。 XPath使节点/元素搜寻超级容易。 一旦取消了不包含Part Number关键字的<p>标记的资格,则正则表达式模式仍然是一种合适的工具。

代码:( 演示

$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 &ndash; 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: "

正则表达式模式使用单词边界元字符\\b )来区分零件编号和非零件编号。 如果由于问题中未包含某些数据而需要调整模式,请告知我们,我们将提供进一步的指导。

最终,我调情了一个纯正则表达式解决方案,该解决方案将\\G包含在“ Part Number:或之前的匹配之后以“继续”匹配,但是这种类型的模式很难概念化,并且dom解析器再次是更稳定的工具与正则表达式处理有效的html时。

如果我正确理解了您的问题,则应该可以执行以下操作:

Part\\sNumber:\\s(\\d{5})

假设您的字符串包含所有的Part Number ,如下所示:

<p>Part Number: 67001</p>

<p>Part Number: 50545 &ndash; 450g Cartridge 50525 - 2.5kg Tub 50520 - 20kg Pail 50555 - 55kg Drum 50575 *Indent - 175kg Drum</p>

<p>Part Number: 23425 - 55kg Drum 50575 *Indent - 175kg Drum</p>

<p>Part Number: 52232</p>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM