首先,我不是正则表达式的专业人士,而且依赖于this cookbook,this tool和this other tool
现在当我尝试运行它时,python 2.7.7 64bit win 8它对这个示例文本什么都不做
两周前,我一直在追赶目标并花费了1,010.53美元并获得了300分。当我查看余额后,我只有1912.04美元。
请注意,美元加入金额(USD1,010.53)并且在第一种情况下每千人有一个逗号,但第二种情况下它没有加入金额,并且第1000位没有逗号(USD 1912.04)并且在某些情况下,它们是一些整数但不是货币的值,仍然需要解析。(300分)。
现在我设法抓住了这个
[0-9] {1,3}([0-9] {3})* \ B([0-9] +。)?|。[0-9] + \ B'/ P >
现在我有两个问题:
regex = re.compile('[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?\b|\.[0-9]+\b')
mynumerics = re.findall(regex,'The final bill is USD1,010.53 and you will earn 300 points. Thank you for shopping at Target')
我期望的是三个项目:
=>['1,010.53', '300', '1912.04']
或更好
=>[1010.53, 300, 1912.04]
相反,我得到的只是一个空列表。我可能会尝试下载不同版本的python,但我知道我们使用2.7.X部署的大多数产品。所以我希望它不是版本问题。
答案 0 :(得分:4)
两个主要问题:
re.findall
将返回元组列表。由于您的模式以非常奇怪的方式使用组,您最终会看到一些奇怪的结果。使用(?:
而不是简单的(
括号来使用非捕获组。
因为如果使用\b
,您应该将模式字符串指定为带有r'string'
的原始字符串。实际上,你的所有正则表达式都应该使用原始字符串来确保没有任何东西被奇怪地解析。
考虑到这些,这完全没问题:
>>> regex = re.compile(r'[0-9]{1,3}(?:,[0-9]{3})*(?:\.[0-9]+)?\b|\.[0-9]+\b')
>>> mynumerics = re.findall(regex,'The final bill is USD1,010.53 and you will earn 300 points. What about .25 and 123,456.12?')
>>> mynumerics
['1,010.53', '300', '.25', '123,456.12']
请注意您的模式与我的模式之间的一些特殊差异。
r'[0-9]{1,3}(?:,[0-9]{3})*(?:\.[0-9]+)?\b|\.[0-9]+\b'
1 2 2
'[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?\b|\.[0-9]+\b'
1 - raw string
2 - non-capturing groups instead of capturing groups
据我所知,有些方式超出了你的想法,如果你需要澄清请注释,我可以根据需要进行编辑。我建议查看一些其他的正则表达式引用和提示,我个人喜欢this site并且几乎虔诚地使用它来满足任何正则表达式的需要。
正如Mark Dickinson巧妙地指出的那样,原始正则表达式中的|\.[0-9]+
用于匹配.24
(简单小数)之类的东西。我将该部分添加回来并添加到匹配的字符串中以显示功能。
旁注:这个模式,如图所示,将看到4400并返回400,或a123并返回123.这是一个问题(不是@ RNar的,原始模式有相同的问题)因为如果4400应该被忽略,那么你不应该得到它的一部分(只是在前面添加\ b导致其他问题,因此它比那更难),并因为English digit grouping rules allow the omission of the comma when the value is four digits to the left of the decimal, between 1000 and 9999,所以你不会匹配那些正如所写
答案 1 :(得分:2)