正则表达式捕获字符串的两个部分

时间:2019-02-17 08:53:03

标签: python regex python-3.x

我正在抓取一些数据。数据点之一是锦标赛奖池。数据中有许多不同的货币。我想从每个值中提取金额和货币,以便可以使用Google将其转换为基础货币。但是,自从我使用正则表达式已经有一段时间了,所以至少可以说我很生疏。数据的可能格式如下:

$534
$22,136.20
3,200,000 Ft HUF
12,500 kr DKK
50,000 kr SEK
$3,800 AUD
$10,000 NZD
€4,500 EUR
¥100,000 CNY
₹7,000,000 INR
R$39,000 BRL

下面是我想到的第一个正则表达式。

[0-9,.]+(.+)[A-Z]{3}

但是显然不能捕获金额和货币,所以我更改了它。

([0-9,.]+).+([A-Z]{3})

但是,我无法弄清楚这个正则表达式存在的问题。

  1. ([0-9,.]+)本身可以很好地捕获恰好金额。

  2. 当我在表达式中添加.+时,由于某些原因 ,它会在第一次和第二次测试中停止捕获尾随的40情况分别。 为什么?

  3. 然后,当我添加([A-Z]{3})时,它似乎对所有测试用例都非常有效,但显然在前两个中没有选择。

  4. 所以我将其更改为([A-Z]{0,3}),这似乎破坏了所有内容。

发生了什么事?如何更改表达式以使其起作用?

我在这里:([0-9,.]+)((?:.+)([A-Z]{3}))?

2 个答案:

答案 0 :(得分:2)

这应该有效:

([0-9,.]+).*?([A-Z]{3})?$

我做了一些更改:

  • 我将.+更改为.*?,因为数字后总是不存在某些内容(例如前两种情况)。我在这里使用了惰性匹配,因为否则它将一直匹配到最后。

  • 我将第2组设为?是可选的,因为并非总是货币(前两种情况)

  • 我添加了行末锚$,以使懒惰的.*?匹配某物而不是什么。

如果您不了解“懒惰”在这种情况下的含义,请参见this post

Demo

答案 1 :(得分:1)

对于示例数据,您可以使用一个可选的非捕获组来匹配货币前的空格和字符:

([0-9,.]+)(?:(?: [A-Za-z]+)? ([A-Z]{3}))?

Regex demo

这将匹配

  • (捕获组
    • [0-9,.]+匹配字符类中列出内容的1倍以上
  • )关闭捕获组
  • (?:非捕获组
    • (?: [A-Za-z]+ )?可选组,用于匹配一个空格,是a-zA-Z和空格的1倍以上
    • ([A-Z]{3})捕获3个大写字符
  • )?关闭非捕获组并将其设置为可选