首页 > 解决方案 > 正则表达式:匹配数字字符串直至密码排列

问题描述

我试图找到一个正则表达式查询,例如,以下字符串匹配相同的表达式

或者(另一个示例),以下字符串匹配相同的表达式,但与之前的表达式不同:

也就是说,如果两个字符串具有相同的形式,则它们应该相等,但数字在内部排列,因此它们是成对不同的。

点应该表示序列中的空格,这可以是不是单个数字的任何值,并且两个“相等”的字符串应该在相同的位置有空格。如果有帮助,字符串都具有相同的 81 长度(以上它们的长度都为 15,以免写入太长的字符串)。

也就是说,如果我有一些如上所述的字符串,例如“3566.235.225..45”,我想有一些正则表达式,我可以将其应用于某个数据库以查明这样的字符串是否已经存在

是否有可能做到这一点?

标签: regex

解决方案


答案相当简单:

import re

pattern = re.compile(r'^(\d)\1{3}$')

print(pattern.match('1234'))
print(pattern.match('333'))
print(pattern.match('3333'))
print(pattern.match('33333'))

你捕获你需要的东西一次,然后告诉正则表达式引擎你需要多久重复一次。您可以根据需要随时参考它,例如匹配11.222.1您使用的模式^(\d)\1{1}\.(\d)\2{2}\.(\1){1}$

注意里面的那个{1}是多余的,但它表明模式可以很规则。如此之多,以至于编写一个为您解决问题的函数实际上很容易:

def make_pattern(grouping, separators='.'):
    regex_chars = '.\\*+[](){}^$?!:'

    groups = {}
    i = 0
    j = 0
    last_group = 0
    result = '^'
    while i < len(grouping):
        if grouping[i] in separators:
            if grouping[i] in regex_chars:
                result += '\\'
            result += grouping[i]
            i += 1
        else:
            while i < len(grouping) and grouping[i] == grouping[j]:
                i += 1
            if grouping[j] in groups:
                group = groups[grouping[j]]
            else:
                last_group += 1
                groups[grouping[j]] = last_group
                group = last_group
                result += '(.)'
                j += 1
            result += f'\\{group}{{{i-j}}}'
        j = i
    return re.compile(result+'$')


print(make_pattern('111.222.11').match('aaa.bbb.aa'))

因此,您可以给出make_pattern一个很好的模式示例,它会为您返回已编译的正则表达式。如果您想要除 之外的其他分隔符'.',您也可以将它们传入:

my_pattern = make_pattern('11,222,11', separators=',')
print(my_pattern.match('aa,bbb,aa'))

推荐阅读