繁体   English   中英

正则表达式首先满足长度然后检查其他模式?

[英]regular expression to met length firstly then check other pattern?

我不知道如何用英文标题准确表达问题,有2条规则

  1. 首先,在头部和末端部分尽可能长地满足给定的长度

  2. 然后匹配其他模式

例如,

  1. 必须读取数字前2~3个字符,如果字符串足够长,则必须读取数字后2~4个字符; 如果字符串不够长,则只读
  2. 检查 number 之前的字符是否不是a ,并且 number 之后的字符不是z

--- 编辑于 20220620 ---- 代码正是下表试图表达的内容

import re
lst = {
'abc123defg':'abc123defg',
'babc123defg':'abc123defg',
'aba123defg':'""',
'abc123zefg':'""',
'bc123def':'bc123def',
'c123def':'c123def',
'c123zef':'""',
'c123d':'c123d'
}

reStr = r".{1,2}[^a\d]\d+[^z\d].{1,3}"
reStr = r"^[A-Za-z]{1,2}[B-Zb-z]\d+[A-Ya-y][A-Za-z]{1,3}"

for key, value in lst.items():
    match = re.match(reStr, key, re.IGNORECASE | re.VERBOSE)
    if match:
        print(f'{key:15s} expected to be: {value:15s}, really get: {match.group():15s}')
    else:
        print(f'{key:15s} expected to be: {value:15s}, really get: ""')

--- 以下描述是旧的,我现在没有编辑它

文本 预期的发现 解释
abc123defg abc123defg 首先阅读“abc123defg”,其中c不会中断[^a] ,并且d不会中断[^z] 所以 'abc123defg' 匹配
babc123defg abc123defg 首先阅读“abc123defg”,其中c不会中断[^a] ,并且d不会中断[^z] 所以 'abc123defg' 匹配
aba123defg 没有 首先阅读 'abc123defg',其中a中断[^a] ,而d不中断[^z] 所以''匹配
abc123zefg 没有 首先阅读“abc123defg”,其中c不会中断[^a] ,但z会中断[^z] 所以''匹配
bc123def bc123def 首先阅读'bc123def',其中c不会中断[^a] ,并且d不会中断[^z] 所以 'bc123def' 匹配
c123def c123def 首先阅读 'c123def',其中c不会中断[^a] ,并且d不会中断[^z] 所以'c123def'被匹配
c123zef 没有 首先阅读“c123def”,其中c不会中断[^a] ,而z会中断[^z] 所以 '' 匹配
c123d c123d 首先阅读 'c123d',其中c不会中断[^a] ,并且d不会中断[^z] 所以 'c123d' 匹配

所以我把正则表达式写在 Python

import re
lst = ['abc123defg', 'aba123defg', 'abc123zefg', 'bc123def']

for text in lst:
    print(text, ' -> ', re.match(r".{1,2}[^a]\d*[^z].{1,3}", text, re.IGNORECASE | re.VERBOSE).group())

但是,当然,答案不是预期的

abc123defg  ->  abc123defg
aba123defg  ->  aba123
abc123zefg  ->  abc123zef
bc123def  ->  bc123def

那么有没有办法只用正则表达式来满足期望呢? 谢谢

根据您的描述,我将正则表达式更改为:

r".{1,2}[^a\d]\d+[^z\d].{1,3}"

关键是要正确匹配数字:

  • 至少一个数字: \d+而不是\d*
  • 为了准确知道数字前后的内容,您只需要通过上面提到的\d+来匹配数字。 这就是为什么我在前后“添加” [^\d]的原因。

这 2 条规则可以包含在单个正则表达式模式中。 试试这个表达式:

regex = re.compile("^[A-Za-z]{1,2}[B-Zb-z]\d+[A-Ya-y][A-Za-z]{1,3}")

简单且不言自明:

  • 查找 1 到 2 个字母字符
  • 再找一个字母字符,不包括字符 A | 一种
  • 继续任何数字序列
  • 之后,找到另一个字母字符,不包括字符 Z | z
  • 再找出 1 到 3 个字母字符

然后您将能够以预期的结果重现您的代码。

对于模式不匹配的情况,将需要一个try子句以避免 None 相关的 AttributeErrors:

for text in lst:
try:
    print(text, ' -> ', re.match("^[A-Za-z]{1,2}[B-Zb-z]\d+[A-Ya-y][A-Za-z]{1,3}", text).group())
except AttributeError:
    print(text, ' -> No pattern found')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM