【问题标题】:regex - how to capture two patterns in one group?正则表达式 - 如何在一组中捕获两种模式?
【发布时间】:2020-11-19 12:57:08
【问题描述】:

我想将两种不同的模式捕获到一个捕获/匹配组中。这甚至可能吗?

第一个模式:两个字符的字母数字被空格包围([A-Z0-9]{2})

第二种模式:两个字符的字母数字前面是字母数字和一个十进制值后面跟一个空格\b[A-Z ]*\d+\.\d{2}([A-Z0-9]{2})

这两种模式一起捕获了我想要的一切,但问题是我需要它们位于单个捕获组中并按照捕获的顺序(请参阅预期输出)。

测试字符串

ABC WS PIT342.55USD342.55END
ABC WS YMQ234.03WS TOY234.03USD468.06END
FUR BB LAB Q10.00 199.00USD209.00END
YAS DG TYY Q AWSMSN11.32 2503.08LD VET Q JKLOLE11.32 2503.08USD5028.80END
PPP VP LAP Q10.00 M342.41EE SFD Q10.00 282.24USD644.65END
YAS DL X/XXX MO X/POP DF PSC241.30ET X/SAE DL X/KOO DL CSG269.80USD511.10END

regex101

预期输出

+------------------------------------------------------------------------------+------------------------+
| ABC WS PIT342.55USD342.55END                                                 | WS                     |
| ABC WS YMQ234.03WS TOY234.03USD468.06END                                     | WS, WS                 |
| FUR BB LAB Q10.00 199.00USD209.00END                                         | BB                     |
| YAS DG TYY Q AWSMSN11.32 2503.08LD VET Q JKLOLE11.32 2503.08USD5028.80END    | DG, LD                 |
| PPP VP LAP Q10.00 M342.41EE SFD Q10.00 282.24USD644.65END                    | VP, EE                 |
| YAS DL X/XXX MO X/POP DF PSC241.30ET X/SAE DL X/KOO DL CSG269.80USD511.10END | DL, MO, DF, ET, DL, DL |
+------------------------------------------------------------------------------+------------------------+

【问题讨论】:

  • (?:\b[A-Z ]*\d+\.\d{2}([A-Z0-9]{2}))?([A-Z0-9]{2}) 可以工作吗?
  • 您可以通过转义它们或将它们包含在字符类中 ([ ]) 使正则表达式末端的空格更加明显。
  • 我不确定是否将这两种模式归为一组,但如果您想要预期的输出,那么您也可以使用 2 组来获得它。 (?:\b\w+?\.\d{2})([A-Z]{2}\b)|(\b[A-Z]{2}\b)
  • 我在您提供的链接中对此进行了测试,我可以在一个组中看到这两种模式。试试这个 - (?:\b\w+?\.\d{2})?[^A-Z]([A-Z]{2}\b)

标签: python regex


【解决方案1】:

您可以省略字符类 [A-Z ]* 中的空格,因为它与此部分 WS YMQ234.03WS 中的第一个 WS 不匹配。

由于两个模式都有相同的部分,然后以 2 个字母数字和空格结尾,您可以使用 alternation | 来匹配前面的空格或第二个模式的第一部分。

(?:\b[A-Z]*\d+\.\d{2}| )([A-Z0-9]{2}) 

说明

  • (?: 交替的非捕获组|
    • \b[A-Z]*\d+\.\d{2} 字边界,匹配 0+ 次字符 A-Z,1+ 位,点和 2 位
    • | 匹配一个空格
  • )关闭非捕获组
  • ([A-Z0-9]{2}) 捕获第 1 组,匹配 2 次字母数字

Regex demo | Python demo

示例代码

import re

strings = [
    "ABC WS PIT342.55USD342.55END",
    "ABC WS YMQ234.03WS TOY234.03USD468.06END",
    "FUR BB LAB Q10.00 199.00USD209.00END",
    "YAS DG TYY Q AWSMSN11.32 2503.08LD VET Q JKLOLE11.32 2503.08USD5028.80END",
    "PPP VP LAP Q10.00 M342.41EE SFD Q10.00 282.24USD644.65END",
    "YAS DL X/XXX MO X/POP DF PSC241.30ET X/SAE DL X/KOO DL CSG269.80USD511.10END"
]

for s in strings: 
    print(re.findall(r"(?:\b[A-Z]*\d+\.\d{2}| )([A-Z0-9]{2}) ", s))

输出

['WS']
['WS', 'WS']
['BB']
['DG', 'LD']
['VP', 'EE']
['DL', 'MO', 'DF', 'ET', 'DL', 'DL']

【讨论】:

  • ?: 是做什么的?
  • @nobody 是非捕获组,用于交替|我会补充说明。
猜你喜欢
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
  • 1970-01-01
相关资源
最近更新 更多