使用正则表达式匹配价格,但有例外

时间:2018-03-28 14:54:24

标签: python regex python-3.x

我有一个字符串:

foo bar $ 123.456 bar foo $ 652 $ 1.255.250 bar $ 2.000 foo badword $ 300.000 foo bar $ 123 badword2 $ 400

我希望匹配所有价格,除了“坏词”之后的价格。

匹配度:

123.456
652
1.255.250
2.000
123

不匹配:

badword $ 300.000
badword2 $ 400

我正在使用Python 3.6开发并使用(\d+).(\d+)来捕获到目前为止的价格。

2 个答案:

答案 0 :(得分:2)

模式(\d+).(\d+)将捕获捕获组1和组2中的一个或多个数字,并且点将匹配任何字符。这也符合123a456

捕获价格的一个选项是匹配您不想要的(?:badword|badword2) \$ \d+(?:\.\d+)*,然后使用alternation在组\$ (\d+(?:\.\d+)*)中捕获您想要的内容:

(?:badword|badword2) \$ \d+(?:\.\d+)*|\$ (\d+(?:\.\d+)*)

那就匹配

  • (?:非捕获组
    • badword|badword2匹配坏词
  • )关闭非捕获组
  • \$匹配空格$ whitespace
  • \d+(?:\.\d+)*匹配1位或更多位数后跟(一个点和1位或更多位数)重复0次或更多次
  • |
  • \$匹配空格$ whitespace
  • (捕获群组(您的数字将在此处)
    • \d+(?:\.\d+)*匹配1位或更多位数后跟(一个点和1位或更多位数)重复0次或更多次
  • )关闭捕获组

您可以使用要添加的坏词扩展交替。

答案 1 :(得分:0)

就个人而言,我会使用列表理解来使用这种更加pythonic的方法。它基本上将价格部分(潜在的单词价格)提取到组中,然后删除其单词组包含badword的匹配项,然后只打印价格值。

See code in use here

import re

s = "foo bar $ 123.456 bar foo $ 652 $ 1.255.250 bar $ 2.000 foo badword $ 300.000 foo bar $ 123 badword2 $ 400"
r = re.compile(r"([^$]+)\$\s*(\d{1,3}(?:\.\d{3})*)")
print([x[1] for x in r.findall(s) if "badword" not in x[0]])

上面代码中使用的正则表达式是:

([^$]+)\$\s*(\d{1,3}(?:\.\d{3})*)

也可以使用以下正则表达式:

([^$]+)\$\s*([\d.]+)
相关问题