【问题标题】:specifying regular expression preference (order of precedence important)指定正则表达式首选项(优先顺序很重要)
【发布时间】:2015-02-13 04:15:53
【问题描述】:

我有以下正则表达式试图从字符串中解析价格:

  $pattern = '#([Ii][Dd][Rr].?\s*[0-9.,]+)|
                ([Rr][Pp].?\s*[0-9.,]+)|
                ([Pp][Rr][Ii][Cc][Ee]:?\s*[0-9.,]+)|
                (\s[0-9]+\s?[Kk]\s)|
                ([0-9]+[Rr][Bb])|
                ([0-9.,]+\s*[Rr][Ii][Bb][Uu])|
                (\b[0-9]+[.,][0-9]+[.,]?[0-9]+)#u';
 $matches = array();
 preg_match($pattern, $caption, $matches);

当使用以下字符串进行测试时:

"ABBY TOP
 Colour : POLKA BLACK
 Weight : 0,18
 Price : 185,000
 Material : Kaos Semi-Fleece
 Size : Panjang / Length: 55 cm (depan), 72 (belakang)"

这总是将0.18 解析为价格,而我希望Price: 185,000 成为实际价格。 我的正则表达式有什么问题吗?

【问题讨论】:

  • 你到底想匹配什么?最后一个可选匹配 ((\b[0-9]+[.,][0-9]+[.,]?[0-9]+)) 将匹配任何数字,即使它在到达单词“price”或其他匹配之前命中它。你真的需要那个小组吗?
  • 不要为此使用正则表达式。只需在换行符上拆分字符串,然后在 : 上再次拆分以生成键值对。
  • 我想我想让它更紧密,使其匹配 3 位(千)或 3 位(百万),所以 2.00 应该是无效的,但 2.000 是有效的.. 我尝试通过更改来强制执行此操作它到 (\b[0-9]+[.,][0-9]{3}[.,]?[0-9]{3})#u';但这不起作用

标签: php regex


【解决方案1】:

无意冒犯,但是......在我给你答案之前,让我指出你的正则表达式中应用的许多修复。

当您尝试双重大小写匹配时,[Ii][Dd][Rr] 不是一个好主意:照常使用idr,但包括case-insensitive flag: #i

Using \d over [0-9] makes the world happier.

此外,您的 Price 条目是 Price : 185,000,但子模式 ([Pp][Rr][Ii][Cc][Ee]:?\s*[0-9.,]+) 不会捕获它,因为冒号前有空格。添加\s*

另见:

现在回到考虑优先级的问题。您可以使用来自this other answer of mine 的相同技术,这使得您的正则表达式:

/^.*?\Kidr.?\s*[\d.,]+|
.*?\Krp.?\s*[\d.,]+|
.*?\Kprice:?\s*[\d.,]+|
.*?\K\s\d+\s?k\s|
.*?\K\d+rb|
.*?\K[0-9.,]+\s*ribu|
.*?\K\b\d+[.,]\d+[.,]?\d+/xis
Regex101 Demo

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 2012-07-04
    • 2013-08-03
    • 2020-02-23
    • 1970-01-01
    相关资源
    最近更新 更多