带条件的正则表达式

时间:2021-03-14 10:25:40

标签: python regex

我一直在使用 python 代码从文本文档中提取文档 ID,其中 ID 可以使用正则表达式位于文本中的随机行。

此文档 ID 由四个字母、一个连字符、三个数字和可选的以字母结尾的字母组成。例如,以下每个都是有效的文档 ID:

  1. ABCD-123
  2. ABCD-123V
  3. XKCD-999
  4. COMP-200

我尝试使用以下正则表达式来查找所有 ID:

re = re.findall(r"([A-Z]{4})(-)([0-9]{3})([A-Z]{0,1})", text.read())

这些表达式可以正常工作,但是当 Id 连接到以下单词时出现问题:

XKCD-999James

正则表达式应该返回 XKCD-999 但它返回的是不正确的 XKCD-999J

我应该在 RE 中做哪些更改才能得到正确的结果?

3 个答案:

答案 0 :(得分:3)

使用否定前瞻断言忽略带有尾随字母的模式:

exp = re.findall(r"([A-Z]{4})(-)([0-9]{3})([A-Z](?![A-Za-z]))?", text.read())
#                                         ^^^^^^^^^^^^^^^^^^^^

答案 1 :(得分:2)

当您使用单词字符时,您可以选择匹配字符 A-Z 后跟单词边界。

\b[A-Z]{4}-[0-9]{3}(?:[A-Z]\b)?

Regex demo

请注意,使用 re.findall 将返回捕获的组,因此如果您只想返回整个匹配项,则可以省略组。

使用捕获组,模式可以是:

\b([A-Z]{4})(-)([0-9]{3}(?:[A-Z]\b)?)

Regex demo

答案 2 :(得分:1)

如何使用边界操作 \b

[A-Z]{4}-\d{3}(?:[A-Z]\b)?

Regex101 示例 - https://regex101.com/r/DhC5Vd/4

text = "XKCD-999James"
exp = re.findall(r"[A-Z]{4}-\d{3}(?:[A-Z]\b)?", text)
#OUTPUT: ['XKCD-999']
相关问题