【问题标题】:How to match a strings with 1 digit and 4 letters that one letter repeat exactly twice and the rest different from each other如何匹配具有 1 个数字和 4 个字母的字符串,其中一个字母恰好重复两次,其余字母彼此不同
【发布时间】:2018-09-06 22:53:53
【问题描述】:

我需要正则表达式来匹配长度为 5 的单词,该单词包含 1 个数字 (0-9) 和 4 个小写字母 (a-z),但其中一个字母重复 恰好 两次并且 rest 彼此不同。

正确匹配示例:

aa1bc  
2adba  
v4alv  

错误匹配示例:

aa1bbc   => notice that although one letter (a) repeat twice,
            other letters are not different from each other (bb)  
1aaaa  
b3ksl  

我使用^(?=.{5}$)[a-z]*(?:\d[a-z]*)(.*(.).*\1){1}$ 来匹配所有包含 1 个数字和 4 个字母的单词,但我不知道如何确保只有一个字母完全重复两次,其余的则不同。

【问题讨论】:

  • 为什么一定要正则表达式?
  • 你还没有问过这个问题吗?
  • @UnbearableLightness 是关于团体的。现在我想了解具体的群体。
  • @zvone 因为我有递归脚本,它为我提供了所有 1 位数字和 4 个字母的单词组合,我想提取这个特定的模式。我认为它可以比编写一个可以做到这一点的脚本更快。
  • 我看不出正则表达式会比执行此操作的函数更快。它会更快、更易读、更容易实现。

标签: python regex


【解决方案1】:

维护一个dictionary 以跟踪string 的每个character 的频率

(cmets 内联)

def is_it_correct(inp):
    if(len(inp) != 5):
        return False
    # store characters in a dictionary; key=ASCII of a character, value=it's frequency in the input string
    ind = 0
    dictionary = dict()
    while(ind < len(inp)):
        cur_char = inp[ind]
        cur_int = ord(cur_char)
        if(dictionary.get(cur_int) == None):
            dictionary[cur_int] = 1
        else:
            dictionary[cur_int] = dictionary[cur_int]+1
        ind = ind+1
    # Make sure there's only one digit (0-9) i.e ASCII b/w 48 & 57
    # Also, make sure that there are exactly 4 lower case alphabets (a-z) i.e ASCII b/w 97 & 122
    digits = 0
    alphabets = 0
    for key, val in dictionary.items():
        if(key >= 48 and key <= 57):
            digits = digits+val
        if(key >= 97 and key <= 122):
            alphabets = alphabets+val
    if(digits != 1 or alphabets != 4):
        return False
    # you should have 4 distinct ASCII values as your dictionary keys (only one ASCII is repeating in 5-length string)
    if(len(dictionary) != 4):
        return False
    return True

ret = is_it_correct("b3ksl")
print(ret)

【讨论】:

    【解决方案2】:

    试试下面的,你不需要正则表达式:

    >>> import random,string
    >>> l=random.sample(string.ascii_lowercase,4)
    >>> l.append(str(random.randint(0,10)))
    >>> random.shuffle(l)
    >>> ''.join(l)
    'iNx1k'
    >>> 
    

    或者如果想要更多:

    import random,string
    lst=[]
    for i in range(3):
        l=random.sample(string.ascii_lowercase,4)
        l.append(str(random.randint(0,10)))
        random.shuffle(l)
        lst.append(''.join(l))
    

    更新:

    import random,string
    lst=[]
    for i in range(3):
        l=random.sample(string.ascii_lowercase,4)
        l[-1]=l[0]
        l.append(str(random.randint(0,10)))
        random.shuffle(l)
        lst.append(''.join(l))
    print(lst)
    

    回答你的问题:

    import re
    def check(val):
        return len(set(val))!=len(val) and len(re.sub('\d+','',val)) and val.islower() and len(val)==5
    a = check("a1abc")
    print(a)
    

    【讨论】:

    • 但是我有很多单词:aab2b、a1clg、alda2 等,我需要找出谁有重复的字母,而其他的字母不同。我不明白你的代码如何帮助我。我只是生成随机字符串。
    • @E235 编辑我的
    • 这不是我的意思。您的代码只是生成与我的问题无关的字符串。我指定匹配应该只在一个字母重复两次而其余不同的字符串上:aba1c、dkld2 等。
    • 这篇文章没有回答这个问题,而是创建了新的字符串,这不是 OP 的意图
    • 投反对票?如果我这样做,我会在一小时前完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 2022-11-04
    相关资源
    最近更新 更多