Kev*_*uan 56 python regex python-2.7
我试图捕获一个字母在一个字符串中出现两次使用RegEx(或者可能有更好的方法?),例如我的字符串是:
ugknbfddgicrmopn
Run Code Online (Sandbox Code Playgroud)
输出将是:
dd
Run Code Online (Sandbox Code Playgroud)
但是,我尝试过类似的东西:
re.findall('[a-z]{2}', 'ugknbfddgicrmopn')
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,它返回:
['ug', 'kn', 'bf', 'dd', 'gi', 'cr', 'mo', 'pn'] # the except output is `['dd']`
Run Code Online (Sandbox Code Playgroud)
我也有办法获得期望输出:
>>> l = []
>>> tmp = None
>>> for i in 'ugknbfddgicrmopn':
... if tmp != i:
... tmp = i
... continue
... l.append(i*2)
...
...
>>> l
['dd']
>>>
Run Code Online (Sandbox Code Playgroud)
但那太复杂了......
如果是'abbbcppq',那么只抓住:
abbbcppq
^^ ^^
Run Code Online (Sandbox Code Playgroud)
所以输出是:
['bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
然后,如果是的话'abbbbcppq',抓bb两次:
abbbbcppq
^^^^ ^^
Run Code Online (Sandbox Code Playgroud)
所以输出是:
['bb', 'bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
Avi*_*Raj 50
您需要使用基于捕获组的正则表达式并将正则表达式定义为原始字符串.
>>> re.search(r'([a-z])\1', 'ugknbfddgicrmopn').group()
'dd'
>>> [i+i for i in re.findall(r'([a-z])\1', 'abbbbcppq')]
['bb', 'bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
要么
>>> [i[0] for i in re.findall(r'(([a-z])\2)', 'abbbbcppq')]
['bb', 'bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
请注意,re.findall这里应返回元组列表,其中第一个组匹配的字符为第一个元素,第二个组为第二个元素.对于我们的情况,第一组中的字符就足够了所以我提到了i[0].
Kas*_*mvd 32
作为Pythonic方式您可以zip在列表理解中使用函数:
>>> s = 'abbbcppq'
>>>
>>> [i+j for i,j in zip(s,s[1:]) if i==j]
['bb', 'bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
如果你正在处理大字符串,你可以使用iter()函数将字符串转换为迭代器并用于itertols.tee()创建两个独立的迭代器,然后通过调用next第二个迭代器上的函数消耗第一个项目并使用调用zip类(在Python 2.X中使用)itertools.izip()使用此迭代器返回迭代器).
>>> from itertools import tee
>>> first = iter(s)
>>> second, first = tee(first)
>>> next(second)
'a'
>>> [i+j for i,j in zip(first,second) if i==j]
['bb', 'bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
RegEx配方基准:# ZIP
~ $ python -m timeit --setup "s='abbbcppq'" "[i+j for i,j in zip(s,s[1:]) if i==j]"
1000000 loops, best of 3: 1.56 usec per loop
# REGEX
~ $ python -m timeit --setup "s='abbbcppq';import re" "[i[0] for i in re.findall(r'(([a-z])\2)', 'abbbbcppq')]"
100000 loops, best of 3: 3.21 usec per loop
Run Code Online (Sandbox Code Playgroud)
如果您只想匹配一对bin字符串,就像"abbbcppq"您可以使用的那样finditer()返回匹配对象的迭代器,并使用group()方法提取结果,那么在注释中提到的最后一次编辑之后:
>>> import re
>>>
>>> s = "abbbcppq"
>>> [item.group(0) for item in re.finditer(r'([a-z])\1',s,re.I)]
['bb', 'pp']
Run Code Online (Sandbox Code Playgroud)
注意,这re.I是IGNORECASE标志,它使RegEx也匹配大写字母.
使用反向引用,非常简单:
import re
p = re.compile(ur'([a-z])\1{1,}')
re.findall(p, u"ugknbfddgicrmopn")
#output: [u'd']
re.findall(p,"abbbcppq")
#output: ['b', 'p']
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,您可以在perl中引用类似的问题:正则表达式匹配任何重复的字符超过10次
没有正则表达式很容易:
In [4]: [k for k, v in collections.Counter("abracadabra").items() if v==2]
Out[4]: ['b', 'r']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5415 次 |
| 最近记录: |