我的测试中有以下数据:
>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
。
您可以利用 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
(?=<)
正向前瞻,断言 <
向右例如:
$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',
)
您想使用 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
)
)
我认为没有令人信服的理由来实施正则表达式技术。 我发现使用 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)
}