检查字符串Python中的模式

时间:2019-04-10 15:36:26

标签: python string parsing

假设我们有以下类型的字符串:

test= '--a-kbb-:xx---xtx:-----x--:---g-x--:-----x--:------X-:XXn-tt-X:l--f--O-'

就是说,它们总是由:分隔的8个部分组成,因此可以将字符串分成一个列表,每个元素对应一个部分:

testsep = test.split(':')

给予

['--a-kbb-', 'xx---xtx', '-----x--', '---g-x--', '-----x--', '------X-', 'XXn-tt-X', 'l--f--O-']

现在,我要检查字符串test是否足够使连续的3个部分中的x出现在该部分的相同位置。例如,使用上面给出的test,我们发现至少一种这样的情况:从1开始,第2,3和4部分在同一位置(即索引6)包含x。因此,我们的测试字符串与所需的模式匹配。

  • 是否存在一种简单的(也许是功能性的)方法来检查给定的字符串,这些字符串始终由上述格式组成?

天真的方法是拆分,然后遍历所有节,看看是否在每个可能的位置(第一个索引1、2 ...最多8个)都具有x的连续节,但那不会像python一样。

3 个答案:

答案 0 :(得分:2)

一种可能性是将itertools.groupbyclass一起使用,以对在同一位置都具有x的所有字符串进行分组:

from itertools import groupby
class X:
  def __init__(self, _x):
    self.x = _x
  def __eq__(self, _val):
    return any(a == 'x' and b =='x' for a, b in zip(self.x, _val.x))

d = ['--a-kbb-', 'xx---xtx', '-----x--', '---g-x--', '-----x--', '------X-', 'XXn-tt-X', 'l--f--O-']
result = [[a, [i.x for i in b]] for a, b in groupby(list(map(X, d)))]
final_result = [b for _, b in result if any(all(h == 'x' for h in c) for c in zip(*b))] 

输出:

[['xx---xtx', '-----x--', '---g-x--', '-----x--']]

但是,使用幼稚的方法要简单得多,并且确实,该解决方案是Pythonic的:

def group(d):
  start = [d[0]]
  for i in d[1:]:
    if any(all('x' == c for c in b) for b in zip(*(start+[i]))):
       start.append(i)
    else:
       if len(start) > 1:
         yield start
       start = [i]

print(list(group(d)))

输出:

[['xx---xtx', '-----x--', '---g-x--', '-----x--']]

答案 1 :(得分:2)

这够蟒蛇了吗?

str = '--a-kbb-:xx---xtx:-----x--:---g-x--:-----x--:------X-:XXn-tt-X:l--f--O-'
sections = str.split (':')
reduce (lambda a, b: a | ('xxx' in b), [reduce(lambda c, d: c + d, map(lambda c: c[i], sections), '') for i in range(reduce (lambda e, f: max (e, len (f)), sections, 0))], False)

说明

reduce (lambda e, f: max (e, len (f)), sections, 0)

计算最大段长;

for i in range(reduce (lambda e, f: max (e, len (f)), sections, 0))

i的值从0减去最大段长减去1;

map(lambda c: c[i], sections)

计算所有节的第i个字符列表;

reduce(lambda c, d: c + d, map(lambda c: c[i], sections), '')

计算所有部分的第i个字符组成的字符串;

[reduce(lambda c, d: c + d, map(lambda c: c[i], sections), '') for i in range(reduce (lambda e, f: max (e, len (f)), sections, 0))]

计算字符串列表,其中第i个字符串由所有节的第i个字符组成;

如果在上一步计算的列表中的任何字符串包含三个连续的'x',则最终表达式返回True

答案 2 :(得分:2)

每9个元素中选择一个,并检查是否有3个连续的'x':

test= '--a-kbb-:xx---xtx:-----x--:---g-x--:-----x--:------X-:XXn-tt-X:l--f--O-'
for i in range(9):
    if 'xxx' in test[i::9]:
        print("Pattern matched at position %d" % i)
        break
else:
    print("Pattern not matched")

给予

Pattern matched at position 5

简短版本:

>>> any(('xxx' in test[i::9] for i in range(9)))
True