我一直在编写python代码,从文本文档中提取文档ID,其中ID可以使用regex位于文本中的随机行。
此文档ID由四个字母、一个连字符、三个数字组成,可以选择以字母结尾。例如,以下各项都是有效的文档ID:
- ABCD-123
- ABCD-123V
- XKCD-999
- 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中做哪些更改才能得到正确的结果?
使用负前瞻断言来忽略带有尾随字母的模式:
exp = re.findall(r"([A-Z]{4})(-)([0-9]{3})([A-Z](?![A-Za-z]))?", text.read())
# ^^^^^^^^^^^^^^^^^^^^
当您使用单词字符时,您可以选择匹配字符a-Z和单词边界。
b[A-Z]{4}-[0-9]{3}(?:[A-Z]b)?
Regex演示
请注意,使用re.findall将返回捕获的组,因此如果您只想返回整个匹配,可以省略这些组。
对于捕获组,模式可以是:
b([A-Z]{4})(-)([0-9]{3}(?:[A-Z]b)?)
Regex演示
使用边界运算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']