我一直在使用 python 代码从文本文档中提取文档 ID,其中 ID 可以使用正则表达式位于文本中的随机行。
此文档 ID 由四个字母、一个连字符、三个数字和可选的以字母结尾的字母组成。例如,以下每个都是有效的文档 ID:
我尝试使用以下正则表达式来查找所有 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 中做哪些更改才能得到正确的结果?
答案 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)?
请注意,使用 re.findall 将返回捕获的组,因此如果您只想返回整个匹配项,则可以省略组。
使用捕获组,模式可以是:
\b([A-Z]{4})(-)([0-9]{3}(?:[A-Z]\b)?)
答案 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']