匹配交替的数字和字符

时间:2011-08-22 19:33:28

标签: python regex

我已阅读有关正则表达式的Google python正则表达式教程,并尝试测试我需要的其中一种模式。

  • 字符串长度必须为10个字符。
  • 1,3,5,7,9个字符必须是数字(1 - 5)且不应重复
  • 其他符号是字母(a,b或c),可以重复

例如:

1a2b4a3c5b # is valid

1a5c4b4a3b # is not valid because of two 4s

到目前为止,我已经尝试过:

pattern = r'([1-5])[abc]([1-5^\1])[abc]([1-5^\1\2])[abc]([1-5\1\2\3])[abc]([1-5\1\2\3\4])[abc]'

但它失败了......

3 个答案:

答案 0 :(得分:4)

您尝试在否定的字符类中包含先前的匹配,这是不可能的。

执行此操作的唯一方法是执行以下操作:

^([1-5])[abc](?!\1)([1-5])[abc](?!\1|\2)([1-5])[abc](?!\1|\2|\3)([1-5])[abc](?!\1|\2|\3|\4)[1-5][abc]$

毋庸置疑,这不是正则表达式应该做的事情。

演示:

#!/usr/bin/env python

import re

tests = ['1a2b4a3c5b', '1a5c4b4a3b']

pattern = re.compile(
    r"""(?x)             # enable inline comments and ignore literal spaces
    ^                    # match the start of input
    ([1-5])              # match any of '1'..'5' and store it in group 1
    [abc]                # match 'a', 'b' or 'c'
    (?!\1)([1-5])        # if the digit from group 1 is not ahead, match any of '1'..'5' and store it in group 2
    [abc]                # match 'a', 'b' or 'c'
    (?!\1|\2)([1-5])     # if the digits from group 1 and 2 are not ahead, match any of '1'..'5' and store it in group 3
    [abc]                # match 'a', 'b' or 'c'
    (?!\1|\2|\3)([1-5])  # if the digits from group 1, 2 and 3 are not ahead, match any of '1'..'5' and store it in group 4
    [abc]                # match 'a', 'b' or 'c'
    (?!\1|\2|\3|\4)[1-5] # if the digits from group 1, 2, 3 and 4 are not ahead, match any of '1'..'5'
    [abc]                # match 'a', 'b' or 'c'
    $                    # match the end of input
    """, re.X)

for t in tests:
  if re.match(pattern, t):
    print t

会打印:

1a2b4a3c5b

答案 1 :(得分:4)

我会建议像这样的东西而不是正则表达式:

def matches(s):
    return (len(s) == 10 and 
            set(s[::2]) == set('12345') and 
            set(s[1::2]) <= set('abc'))

>>> matches('1a2b4a3c5b')
True
>>> matches('1a5c4b4a3b')
False

答案 2 :(得分:1)

您可以使用否定前瞻来确定下一个数字是否不是之前的数字。以下正则表达式应该有效:

pattern = r'^([1-5])[abc](?!\1)([1-5])[abc](?!\1|\2)([1-5])[abc](?!\1|\2|\3)([1-5])[abc](?!\1|\2|\3|\4)([1-5])[abc]$'

编辑正如Bart指出的那样,正则表达式应以^开头,并以$结束,以确保它只与该字符串完全匹配