Regexp变量字母数字匹配

Regexp变量字母数字匹配,regex,Regex,我正在尝试匹配以下示例: ZU2A ZS6D-9 ZT0ER-7 ZR6PJH-12 它是字母和数字(字母数字)的组合。 下面是一个解释: 它总是以大写字母Z开头 后面始终只有一(1)个R、S、T或U“[R | S | T | U]” 始终只后跟一(1)个数字“[0-9]” 后跟至少一(1)个大写字母(大写字母)和最多三(3)个大写字母(大写字母),如[a-Z]{1,3} (可选)后跟“-”,最少一(1)个数字,最多两(2)个数字 目前,我有以下几点: Z[R|S|T|U][0-9][A-Z]

我正在尝试匹配以下示例:

ZU2A ZS6D-9 ZT0ER-7 ZR6PJH-12
它是字母和数字(字母数字)的组合。 下面是一个解释:

  • 它总是以大写字母Z开头
  • 后面始终只有一(1)个R、S、T或U“[R | S | T | U]”
  • 始终只后跟一(1)个数字“[0-9]”
  • 后跟至少一(1)个大写字母(大写字母)和最多三(3)个大写字母(大写字母),如[a-Z]{1,3}
  • (可选)后跟“-”,最少一(1)个数字,最多两(2)个数字
  • 目前,我有以下几点:

    Z[R|S|T|U][0-9][A-Z]{1,}(\-)?([0-9]{1,3})
    
    但这似乎并没有抓住所有的样本

    编辑:以下是完整字符串的示例:

    ZU0D>APT314,ZT1ER,WIDE1,ZS3PJ-2,ZR5STU-12*/V:/021414z2610.07S/02814.02Ek067/019/A=005475!w%<!
    
    ZU0D>APT314,ZT1ER,WIDE1,ZS3PJ-2,ZR5STU-12*/V:/021414z2610.07S/02814.02Ek067/019/A=005475!w%
    任何帮助都将不胜感激

    多谢各位


    Danny

    您的主要问题是,整个可选部分应该由一组标有
    (=可选)的括号包围。总之,你想要什么

    Z[RSTU][0-9][A-Z]{1,3}(?:-[0-9]{1,2})?
    
    还有几个额外的注意事项:

    • 在字符组中,您可以简单地列出字符。因此,对于2,您需要
      [RSTU]
      (?:R|S|T|U)
    • (?:example)
      而不是
      (example)
      形式的组阻止子表达式作为匹配项返回。它对匹配哪些输入没有影响
    • 您不需要在字符类之外使用反斜杠转义
      -
    这是一个:

    重新导入
    s=r'Z[RSTU][0-9][A-Z]{1,3}(?:-[0-9]{1,2})'
    rex=重新编译
    对于(‘ZU2A’、‘ZS6D-9’、‘ZT0ER-7’、‘ZR6PJH-12’)中的试验:
    assert rex.match(测试),test
    
    长测试='ZU0D>APT314、ZT1ER、WIDE1、ZS3PJ-2、ZR5STU-12*/V:/021414z2610.07S/02814.02Ek067/019/A=005475!RE中的w%最后计数应为
    {1,2}
    。为什么要关闭
    ?贪婪行为和非贪婪行为在这里会有什么不同?@user1016274谢谢,最后将3替换为2<代码>?
    仅当紧跟在
    *
    +
    之后时表示贪婪。如果没有上述任何一种方法,
    是编写
    {0,1}
    的一种简单方法。不包括可选的尾随部分不是必需的,实际上只返回部分匹配(如您所注意的)。所以,与其说是
    (?:)?
    ,不如说是
    (?:)?
    ,对吧?我不知道你所说的只返回部分匹配是什么意思。成功匹配的结果对象将有一个组
    0
    ,该组匹配所有内容。如果我们使用您的建议
    ^Z[RSTU][0-9][A-Z]{1,3}([0-9]{1,3})$
    ,结果的组1有时包含字符串,有时不包含字符串(取决于regexp实现,它在某些情况下也可能不存在)。这意味着分配和复制部分匹配字符串的额外开销,以及有人意外使用组1的可能性。不匹配任何人都不想匹配的东西会更快更干净。
    import re
    
    s = r'Z[RSTU][0-9][A-Z]{1,3}(?:-[0-9]{1,2})?'
    
    rex = re.compile(s)
    for test in ('ZU2A', 'ZS6D-9', 'ZT0ER-7', 'ZR6PJH-12'):
        assert rex.match(test), test
    
    long_test = 'ZU0D>APT314,ZT1ER,WIDE1,ZS3PJ-2,ZR5STU-12*/V:/021414z2610.07S/02814.02Ek067/019/A=005475!w%<!'
    found = rex.findall(long_test)
    assert found == ['ZU0D', 'ZT1ER', 'ZS3PJ-2', 'ZR5STU-12'], found