【问题标题】:Preg matching Price预匹配价格
【发布时间】:2014-05-10 16:25:59
【问题描述】:

我使用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>

所需的数学是:

  • 80.00 美元
  • B €19,75
  • C 欧元 149 欧元
  • 149 欧元
  • 149 欧元

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

问题:

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

非常感谢!

【问题讨论】:

  • 嗯...有人写了一个kickass答案,但它刚刚被删除?

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


【解决方案1】:

这样的东西有用吗?

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

[编辑]

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

【讨论】:

  • 很遗憾,格式可以是数字前面或后面的任何货币(符号或字母)(也可能采用不同的格式)。所以我想要的是获取以“价格”开头或结尾的类或 id 的内容
  • 我想我可以做这样的事情((\$|€|EUR)+ *([0-9,]+(\.[0-9]{1,2})?))|(([0-9,]+(\.[0-9]{1,2})?) *(\$|€|EUR)+) 以确保它在之前和之后捕获符号......不过,我必须在预赛中转储所有货币符号,这可行吗?
  • 当然。将它存储在一个变量中,这样你就只维护一个列表,你应该很高兴
【解决方案2】:

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

【讨论】:

  • 感谢您的建议。请问您是如何从该代码中过滤价格的?我不想要 html 的每个节点,只想要包含“价格”的节点。查看我更新的代码。
  • @James:“包含”是什么意思?排队的任何地方?或者在任何父节点的任何地方?
  • @James:如果您尝试在其id 属性中的任何位置查找具有price 的节点,您可以使用XPath 表达式轻松实现。这就是你要找的东西吗?
猜你喜欢
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多