【问题标题】:Python 2.7.7 not working with RegExPython 2.7.7 不适用于正则表达式
【发布时间】:2015-12-16 20:34:52
【问题描述】:

首先我不是正则表达式的专业人士,我一直依赖this cookbookthis toolthis other tool

现在,当我尝试运行它 python 2.7.7 64bit win 8 时,它对这个示例文本没有任何作用

两周前,我冲向目标,花了 1,010.53 美元,获得了 300 积分。当我只有 1912.04 美元后查看余额时。

请注意,美元与金额 (USD1,010.53) 相连,在第一种情况下,每千位有一个逗号,但在第二种情况下,它没有与金额相连,千位 (USD) 没有逗号1912.04),在某些情况下,它们是一些整数但不是货币的值,仍然需要解析。(300 分)。

现在我设法得到了这个

[0-9]{1,3}(,[0-9]{3})*(.[0-9]+)?\b|.[0-9]+\b

现在我有两个问题:

  1. Python 不会为上述正则表达式和示例字符串返回任何值,但工具会这样做。
  2. 仅当每 1000 个位置有一个逗号时,正则表达式才会返回,即 1912.04 美元最终在在线工具上返回 912.04,不太确定如何让它同时使用逗号和非逗号。

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。所以我希望它不是版本问题。

【问题讨论】:

  • 不是版本问题。我在 3.X 中尝试了您的代码,但仍然无法正常工作。此外,请尝试为您的 compile 参数使用原始字符串,这样它就不会无意中将您的斜杠读取为转义序列的开头。
  • "现在我有两个问题:" (link) :^)
  • 旁注:即使固定为“工作”,此模式也会看到4400 并返回400,或a123 并返回123。这可能是个问题,因为如果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,所以4400 应该被接受为“英文格式的数字”而不是。

标签: python regex python-2.7 text-parsing string-parsing


【解决方案1】:

两个主要问题:

  • 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(简单小数)之类的东西。我将该部分重新添加回来,并添加到匹配的字符串中以显示功能。

ShadowRanger 的重要评论

旁注:如所写,此模式将看到 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,所以你不会匹配那些写的

【讨论】:

  • 您进行了另一项未调用的修复(将.s 转义为\.s,因此它们是文字,而不是“任何字符”)。否则完美(这是我为什么要在“在 Python 中使用原始字符串进行正则表达式!!!”的另一个例子)。 :-)
  • 我相信原始正则表达式的最后一部分是为了匹配像“.23”这样的数字,没有明确的组成部分。
  • @ShadowRanger 转义已经在他使用的原始匹配模式中,如果您查看他发布的代码,而不是他“掌握”的模式(它们不一样)
  • 而简化的正则表达式很容易被超越;如果目标是识别 3 个匹配标准逗号分隔规则的组,则匹配 1,2,3 将是错误的。
  • @MarkDickinson aaaahhh 我一定是被分组和括号等绊倒了。将再次添加它。
【解决方案2】:

你能试试这个正则表达式吗?

((?:\d+,?)+\.?\d+)

https://regex101.com/r/qN0gV9/1

【讨论】:

    猜你喜欢
    • 2018-06-26
    • 2019-12-02
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2013-09-08
    相关资源
    最近更新 更多