繁体   English   中英

如何编写正则表达式以查找字符组合,但每个字符只能在python中出现一次

[英]How to write regular expression to find combination of characters, but each can only appear once in python

我想查找字符串中的“ xy”是否可选,“ xy”是否是可选的,因为每个字符只能出现一次。 例如:

def findpat(texts, pat):
    for text in texts:
        if re.search(pat, t):
            print re.search(pat, t).group()
        else:
            print None    

pat = re.compile(r'[xy]*?b')
text = ['xyb', 'xb', 'yb', 'yxb','b', 'xyxb']
findpat(text, pat)

# it prints
# xyb
# xb
# yb
# yxb
# b
# xyxb

对于最后一个,我想要的输出是“ yxb”。 我应该如何修改我的正则表达式? 非常感谢

您可以使用此模式

r'(x?y?|yx)b'

要分解,有趣的部分x?y?|yx将匹配:

  1. 空字符串
  2. 只有x
  3. 只有y
  4. XY
  5. 在替代分支yx

作为建议,当您对正则表达式不太满意并且场景数量很少时,可以简单地强行使用该模式。 这很丑陋,但可以弄清楚您的情况是什么:

r'b|xb|yb|xyb|yxb'

第2部分。

对于通用解决方案,可以做到这一点,但是对于任意数量的字符而不只是{x,y} ,可以使用以下正则表达式样式:

r'(?=[^x]*x?[^x]*b)(?=[^y]*y?[^y]*b)(?=[^z]*z?[^z]*b)[xyz]*b'

我会解释一下:

  • 通过使用前行,您可以使正则表达式光标前进,对于每个位置,您只需“向前看”,看看后面的内容是否符合特定条件。 通过使用此技术,您可以将多个条件组合到一个正则表达式中。
  • 对于光标位置,我们测试集合中的每个字符在该位置最多出现一次,直到匹配目标b字符。 我们使用[^x]*x?[^x]* ,这意味着如果有则匹配not-x,最多匹配一个x,然后匹配任意数量的not x
  • 一旦满足测试条件,我们便开始前进光标并匹配所需集合中的所有字符,直到找到b为止。 在这一点上,我们保证不会重复,因为我们执行了先行测试。

注意:我强烈怀疑它的性能不佳,因为它会回溯。 您只应将其用于小型测试字符串。

测试一下。

您可以使用以下方法:匹配并捕获两组([xy]*)(b) 然后,一旦找到匹配项,请检查组1中值的长度是否与此值中的唯一字符数相同。 如果不是,请从组值的开头删除字符,直到得到一个字符串,该字符串的长度为唯一字符的长度。

就像是:

def findpat(texts, pat):
    for t in texts:
        m = re.search(pat, t)                   # Find a match
        if m:
            tmp = set([x for x in m.group(1)])  # Get the unqiue chars
            if len(tmp) == len(m.group(1)):     # If Group 1 length is the same
                print re.search(pat, t).group() # Report a whole match value
            else:
                res = m.group(1)
                while len(tmp) < len(res):      # While the length of the string is not
                    res = res[1:]               # equal to the number of unique chars, truncate from the left
                print "{}{}".format(res, m.group(2)) # Print the result
        else:
            print None               # Else, no match

pat = re.compile(r'([xy]*)(b)')
text = ['xyb', 'xb', 'yb', 'yxb','b', 'xyxb']
findpat(text, pat)
# => [xyb, xb, yb, yxb, b, yxb]

参见Python演示

好吧,从字面上通过您的测试用例的正则表达式是:

 pat = re.compile(r'(x|y|xy|yx)?b$')

其中“ $”将字符串末尾锚定,从而确保它是找到的最后一个匹配项。

但是,使用正则表达式机制来确保只使用集合中的一个匹配字符会有点棘手...

WiktorStribiżew的评论和演示中 ,我得到了答案。

pat = re.compile(r'([xy]?)(?:(?!\1)[xy])?b')

谢谢大家!

暂无
暂无

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

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