从 HTML 字符串中获取 <span> 包含非零美元金额的文本

问题描述 投票:0回答:3

我的测试中有以下数据:

>0 Dollar</span
>0.01 Dollar</span
>0.00 Dollar</span 
>50.00 Dollar</span

我的愿望:

我想保留不是

0.00 Dollar
0 Dollar
的美元金额。

我正在使用的代码

$str = $table['contents'];
$pattern = "/(Need help here)/";    
$a = preg_match_all($pattern, $str, $matches);
print_r($matches);

输出应该是一个数组,其值为

0.01 Dollar
50.00 Dollar

php html filtering html-parsing text-extraction
3个回答
1
投票

您可以利用 DOMDocument 和 DOMXPath 并在 xpath 查询中使用 preg_match 作为 PhpFunction。

在示例中,我使用了

//span
它将获取所有范围,但您可以使查询更具体地针对您的数据。

$html = <<<HTML
<span>0 Dollar</span>
<span>0.01 Dollar</span>
<span>0.00 Dollar</span>
<span>50.00 Dollar</span>
HTML;

$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xp = new DOMXPath($dom);
$xp->registerNamespace("php", "http://php.net/xpath");
$xp->registerPHPFunctions('preg_match');
$pattern = '/\A(?=[0.]*[1-9])\d+(?:\.\d+)?+\h+Dollar\z/';
$spans = $xp->query("//span[php:functionString('preg_match', '$pattern', text())>0]");

foreach ($spans as $span) {
    echo $span->nodeValue . PHP_EOL;
}

输出

0.01 Dollar
50.00 Dollar

查看 PHP 演示


如果您只想使用正则表达式,则可以匹配前导

>
并断言尾随
<
。如果前面的代码示例,
\A
z
是断言字符串的开头和结尾的锚点。

>\K(?=[0.]*[1-9])\d+(?:\.\d+)?+\h+Dollar(?=<)

模式匹配:

  • >
    按字面意思匹配
  • \K
    忘记到目前为止匹配了什么
  • (?=[0.]*[1-9])
    正向前瞻,断言至少一个数字 1-9,前面有可选的零或点
  • \d+(?:\.\d+)?+
    将 1+ 位数字与可选的小数部分匹配
  • \h+Dollar
  • (?=<)
    正向前瞻,断言
    <
    向右

正则表达式演示 | Php 演示

例如:

$data = <<<DATA
>0 Dollar</span
>0.01 Dollar</span
>0.00 Dollar</span 
>50.00 Dollar</span
DATA;
$regex = '/>\K(?=[0.]*[1-9])\d+(?:\.\d+)?+\h+Dollar(?=<)/';
preg_match_all($regex, $data, $matches);
var_export($matches[0]);

输出

array (
  0 => '0.01 Dollar',
  1 => '50.00 Dollar',
)

0
投票

您想使用 Lookaround,特别是负向前瞻。

$pattern = '#\>((?!0\.00)[0-9\.]+\s+Dollar)\<#';
$a = preg_match_all($pattern, $str, $matches);
print_r($matches);

输出:

Array
(
    [0] => Array
        (
            [0] => >0.01 Dollar<
            [1] => >50.00 Dollar<
        )

    [1] => Array
        (
            [0] => 0.01 Dollar
            [1] => 50.00 Dollar
        )

)

0
投票

我认为没有令人信服的理由来实施正则表达式技术。 我发现使用 DOMDocument 解析 HTML 并使用

sscanf()
解析节点值是隔离所查找值的清晰简洁的方法。 如果您更适合将实际金额转换为浮点值,
sscanf()
通过
%f
占位符提供直接方法。

代码:(演示

$html = <<<HTML
<span>0 Dollar</span>
<span>0.01 Dollar</span>
<span>0.00 Dollar</span>
<span>50.00 Dollar</span>
HTML;

$dom = new DOMDocument();
$dom->loadHTML($html);
$texts = [];
$floats = [];
foreach ($dom->getElementsByTagName('span') as $span) {
    if (sscanf($span->nodeValue, '%f Dollar', $amt) && $amt) {
        $texts[] = $span->nodeValue;
        $floats[] = $amt;
    }
}
var_dump($texts, $floats);

输出:

array(2) {
  [0]=>
  string(11) "0.01 Dollar"
  [1]=>
  string(12) "50.00 Dollar"
}
array(2) {
  [0]=>
  float(0.01)
  [1]=>
  float(50)
}
© www.soinside.com 2019 - 2024. All rights reserved.