我现在有这个正则表达式
/<div[^>]*>|(\d{1,9}\.\d{2})/
检测<div>
的开头,并以货币格式对其进行分组。
如果我有这样的字符串
<div class="foo">Hello world 4546.00 and 6596.45 bla bla bla</div>
我只想用preg_replace
正如您在下面的示例中所看到的,我不希望选择div之外的数字,只选择里面的数字。
答案 0 :(得分:1)
我不确定你为什么如此迅速地投票,但我只能假设这是因为这个问题的主题及其与regex match open tags except xhtml self contained tags的关系。
这绝不是最佳答案,但是,在您的问题范围内,它确实解决了您的问题。
(?:<div[^>]*>|\G(?!\A))(?:(?!</div>).)*?\K\d{1,9}\.\d{2}
如果<div>
标记可能跨越多行,您可以添加s
修饰符,以允许.
匹配换行符as seen here。
dasdfasdf 355.56 asdfasd
<div class="sdaf">sdfsad 36546545643.00 asdfa sdf sadfasdf 544.45 sadfs</div>
dasdfasdf 355.56 asdfasd
dasdfasdf 355.56 asdfasd
<div class="sdaf">sdfsad 36 asdfa sdf sadfasdf sadfs</div>
dasdfasdf 355.56 asdfasd
(?:<div[^>]*>|\G(?!\A))
匹配以下任一项
<div[^>]*>
符合以下条件
<div
按字面意思匹配[^>]*
匹配集合中不存在的任何数字(除>
以外的任何内容)>
按字面意思匹配\G(?!\A)
在上一场比赛结束时断言位置(?:(?!</div>).)*?
Tempered greedy token任意次数匹配任何字符,但尽可能少,并确保不匹配</div>
\K
重置报告的匹配的起点。任何以前消费的字符都不再包含在最终匹配中。\d{1,9}\.\d{2}
匹配1-9位数字,后跟一个文字点.
,后跟2位数字答案 1 :(得分:1)
虽然使用正则表达式解析HTML听起来很有趣,但请使用正确的XML解析器。您可以使用以下DOMDocument
代码来实现此功能:
<?php
$html = 'dasdfasdf 355.56 asdfasd
<div class="sdaf">sdfsad 36546545643.00 asdfa sdf sadfasdf 544.45 sadfs</div>';
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$divs = $doc->getElementsByTagName('div');
foreach($divs as $div)
{
$innerText = $div->nodeValue;
$div->nodeValue = preg_replace('(\d{1,9}\.\d{2})', 'whatever', $innerText);
}
$html = $doc->saveHTML();
var_dump($html);
现在,有了这个,您只需要使用REGEX解析内部字符串而不是<div>
本身。