Preg匹配价格

时间:2014-05-10 16:25:59

标签: php regex preg-match regex-negation regex-lookarounds

我使用http://www.regexr.com/试图了解我正在使用PHP的正则表达式sintaxis。但是,我确信有更好的方法来编写这个表达式:

(?:\"price|price\")+(?:[^\>])*(?:\>)+((?:[^\>](?!\/))+)+(?:[^\>])*(?:\>)*([^\<]*(?!\/\>))

我正在尝试检索以下文字的价格值:

A     <span class="price-sales">$80.00</span>

B <div class="ProdMargin"><font class="items_price" >€19,75</font></div> 
C <div class="price" id="text-price"> foo
<span >EUR 149 €</span>

        </div>
D <div class="price" id="text-foo"> <span >149 €</span></div>
E <div id="text-price" id="foo"> <span >149 EUR</span></div>
F <div class="foo">bar</div>

所需的数据是:

  • A $ 80.00
  • B€19,75
  • C EUR 149€
  • D 149€
  • E 149 EUR

主要问题是我必须创建2个“匹配组”: (A,B)一个用于普通匹配,一个用于二度孩子的(C,D,E)值。

问题:

  • 1)我做错了什么?还是可以改进?
  • 2)我可以只获得一个“匹配组”吗?

非常感谢!

2 个答案:

答案 0 :(得分:1)

这样的事情会起作用吗?

/(\$|€|EUR)? *([0-9,]+(\.[0-9]{1,2})?) *(\$|€|EUR)?/

[编辑]

在这种情况下,我不认为正则表达式是最好的。尝试使用DOM解析器。 PHP有一个内置的。这是一个起点:Getting DOM elements by classname

答案 1 :(得分:1)

HTML不是常规语言,无法使用正则表达式进行可靠解析。请改用DOM解析器。这是使用PHP内置DOMDocument类:

的解决方案
$html = <<<HTML
<span class="price-sales">$80.00</span>
<div class="ProdMargin"><font class="items_price" >€19,75</font></div> 
<div class="price" id="text-price"> foo<span >EUR 149 €</span></div>
<div class="price" id="text-foo"> <span >149 €</span></div>
<div id="text-price" id="foo"> <span >149 EUR</span></div>
HTML;

// Escape entites correctly
$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');

$dom = new DOMDocument;

// Disable errors about the markup
libxml_use_internal_errors(true);

$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

// Find innermost nodes
$nodes = $xpath->query('//*[not(descendant::*)]');

// Loop through the nodes and add items to the array
foreach ($nodes as $node) {
    $results[] = $node->nodeValue;
}

var_dump($results);

输出:

array(5) {
  [0]=>
  string(6) "$80.00"
  [1]=>
  string(8) "€19,75"
  [2]=>
  string(11) "EUR 149 €"
  [3]=>
  string(7) "149 €"
  [4]=>
  string(7) "149 EUR"
}

Demo