如何正确地正则表达式匹配python中的以下字符串?

时间:2014-04-11 14:46:18

标签: python regex

我有以下字符串:

1-婴儿胡萝卜(4Kids)(3美元)[额外0 COUNT]; [需要5个计数]

我想获得以下群组:

Item - 1
Food - Baby Carrots (4Kids) (3 DOLLARS)
Cost - 3
Extra - 0
required - 5

以下是我当前没有拾取任何内容的匹配字符串:

'(?P<item>.+?)\-(?P<food>.*)\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]'

我的尝试出了什么问题?

3 个答案:

答案 0 :(得分:1)

你原来的正则表达式:

(?P<item>.+?)\-(?P<food>.*)\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]

Regular expression visualization

Debuggex Demo

您的问题主要是因为您正在搜索任何字符,而不是特定字符(数字和静态字符串)。例如:为什么使用

(?P<item>.+?)

如果它只是数字?将其更改为

(?P<item>[0-9]+?)

并且在这种情况下不需要'+?':reluctant operator,因为您总是想要整个数字。也就是说,匹配的下一部分将不在该数字的中间中。

此外,这应该固定在line (input) start

^(?P<item>[0-9]+?)

你不需要escape破折号(尽管没有伤害)。

^(?P<item>[0-9]+?)-

你的食物组(heh)是最复杂的部分

(?P<food>.*)

它不仅包含任何字符。根据您的演示输入,它只有字母,空格,数字和parens。所以只搜索它们:

(?P<food>[\w0-9 ()]+)

这是我们到目前为止所拥有的:

^(?P<item>[0-9]+?)- (?P<food>[\w0-9 ()]+)

Regular expression visualization

Debuggex Demo

你会发现这也与成本部分相匹配(你的正则表达式完全没有......我认为这只是一个疏忽)。

添加费用,即

  • (
  • 一个数字
  • [space]DOLLARS)

但只有capture数字:

^(?P<item>[0-9]+?)- (?P<food>[\w0-9 ()]+) \((?P<cost>[0-9]+) DOLLARS\)

其余的正则表达式工作正常,实际上可以按原样添加到结尾:

\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]

但是,我建议将.*?更改为EXTRA[space],如果确实在那里找到了该文本(并且在这种情况下也不需要不情愿)。与[space]COUNT;REQUIRED[space]相同。你缩小范围越多,你的正则表达式就越容易调试 - 假设你的输入确实受到限制。

这是最终版本(还有一个行尾锚点):

^(?P<item>[0-9]+?)- (?P<food>[\w0-9 ()]+) \((?P<cost>[0-9]+) DOLLARS\) \[EXTRA (?P<extra>\d+(\.\d+)?) COUNT\]; \[REQUIRED (?P<required>\d+(\.\d+)?) COUNT\]$

Regular expression visualization

Debuggex Demo


在分析你的正则表达式之前,这就是我想出的:

(?P<item>[0-9]+)- (?P<food>[\w ()]+) \((?P<cost>[0-9]+) DOLLARS\) \[EXTRA (?P<extra>[0-9]+) COUNT\]; \[REQUIRED (?P<required>[0-9]+) COUNT\]

Regular expression visualization

Debuggex Demo


所有这些链接都来自Stack Overflow Regular Expressions FAQ

答案 1 :(得分:0)

像这样:

(?P<item>.+?)\-\s(?P<food>.*?\)).*?\((?P<cost>\d)\s\w+\)\s\[.*?(?P<extra>\d+(\.\d+)?).*\].*\[.*?(?P<required>\d+(\.\d+)?).*\]

演示:http://regex101.com/r/qD1rL9

答案 2 :(得分:0)

如上所述,您缺少捕获成本,您还需要使food捕获非贪婪并包含结束语。我的版本:

(?P<Item>\d)-\s*(?P<Food>.*?\))\s*\((?P<Cost>\d*).*EXTRA\s*(?P<Extra>\d*).*REQUIRED\s*(?P<Required>\d*)

{'Food': 'Baby Carrots (4Kids)', 'Item': '1', 'Required': '5', 'Extra': '0', 'Cost': '3'}

使用http://www.pythonregex.com/

似乎更快一些