如何编写包含贪婪匹配和负查找的组的正则表达式

2024-06-02 07:52:56 发布

您现在位置:Python中文网/ 问答频道 /正文

这应该是一个相当简单的问题,但这是一个让我困扰了很久的问题。我想写一个正则表达式,匹配任意长度的字符串,后跟3-4个大写字母或数字,只要该字符串不以“D”开头,后跟字符串“ABCD”,后跟“.”,后跟三位数字。所以它看起来像这样:

r"(.*)(?<!D[A-Z0-9]{3,4})(ABCD.\d\d\d)"

第二组是我想要捕获/提取的组,我无法正确获取。它需要贪婪匹配(即,只要第一个字母不是D,第四个字符不是“ABCD”字符串中的a,就尝试匹配4个大写字母)。因此,如果我针对以下字符串运行它:

"a \ranDom \ str1ng\DADDABCD.123"
"a diff3r3nt\ranD0m \ str1ng\ DCDZAABCD.123"
"a 3rd\r4ndom \ str1nng\ ADDABCD.123"
"a\ diff3r3nt\ranD0m \ str1ng\CDZAABCD.123"
"a\ diff3r3nt\ranD0m \ str1ng\CDZAABCD-2.123"

它将返回:

None
None
ADD
CDZA
None

2条回答

你可以用

^(.*)\b(?!D)([A-Z0-9]{3,4})(ABCD\.\d{3})$

regex demo。详情:

  • ^-字符串的开头
  • (.*)-组1:尽可能多的任何零个或多个字符
  • \b-单词边界
  • (?!D)-不D立即位于当前位置的右侧
  • ([A-Z0-9]{3,4})-第2组:三个或四个大写ASCII字母或数字
  • (ABCD\.\d{3})-第3组:ABCD.和三位数字
  • $-字符串的结尾

请注意,如果需要匹配文字点字符,则需要转义.

在Python中,使用原始字符串文字定义模式:

pattern = r'^(.*)\b(?!D)([A-Z0-9]{3,4})(ABCD\.\d{3})$'

您可以将此正则表达式与两个先行条件一起使用:

\b(?!D)[A-Z\d]{3,4}(?=ABCD\.\d{3}\b)

RegEx Demo

正则表达式详细信息:

  • \b:单词边界
  • (?!D):向前看以断言D位于下一个位置
  • [A-Z\d]{3,4}:将大写字母或数字匹配3到4次
  • (?=ABCD\.\d{3}\b):向前看,断言当前位置前面有ABCD.后跟3个数字和一个单词边界

代码:

import re

arr = ["a \ranDom \ str1ng\DADDABCD.123",
"a diff3r3nt\ranD0m \ str1ng\ DCDZAABCD.123",
"a 3rd\r4ndom \ str1nng\ ADDABCD.123",
"a\ diff3r3nt\ranD0m \ str1ng\CDZAABCD.123",
"a\ diff3r3nt\ranD0m \ str1ng\CDZAABCD-2.123"]

reg = re.compile(r'\b(?!D)[A-Z\d]{3,4}(?=ABCD\.\d{3}\b)')

for i in arr:
    m = reg.search(i)
    print (m.group() if m else m)

输出:

None
None
ADD
CDZA
None

相关问题 更多 >