python - regEx:匹配两组字符

标签 python regex

我想要一个正则表达式来匹配一些包含字母和数字字符的文本。但我不希望它只匹配字母或数字。 例如。在 python 中:

s = '[mytaskid: 3fee46d2]: STARTED at processing job number 10022001'
#               ^^^^^^^^ <- I want something that'll only match this part.
import re
rr = re.compile('([0-9a-z]{8})')
print 'sub=', rr.sub('########', s)
print 'findall=', rr.findall(s)

生成以下输出:

sub= [########: ########]: STARTED at ########ng job number ########
findall= ['mytaskid', '3fee46d2', 'processi', '10022001']

我希望它是:

sub= [mytaskid: ########]: STARTED at processing job number 10022001
findall= ['3fee46d2']

任何想法... ?? 在这种情况下,它始终恰好是 8 个字符,如果有一个没有 {8} 的正则表达式,那就更好了,即即使多于或少于 8 个字符,它也可以匹配字符。

-- 编辑--

如果有一种方法可以编写 regEx 以便我可以组合 2 个模式(在本例中为 [0-9][a-z]) 并确保匹配的字符串匹配两种模式,但每组匹配的字符数是可变的。例如。也可以是

s = 'mytaskid 3fee46d2 STARTED processing job number 10022001'

-- 回答--

感谢所有人的回答,他们都给了我我想要的,所以每个人都会得到 +1,第一个回答的人会得到被接受的答案。尽管杰里解释得最好。 :)

如果谁是性能的执着者,没有什么可以选择的,他们都是一样的。

s = '[mytaskid: 3fee46d2]: STARTED at processing job number 10022001'
#               ^^^^^^^^ <- I want something that'll only match this part.
def testIt(regEx):
    from timeit import timeit
    s = '[mytaskid: 3333fe46d2]: STARTED at processing job number 10022001'
    assert (re.sub('\\b(?=[a-z0-9]*[0-9])[a-z0-9]*[a-z][a-z0-9]*\\b', '########', s) ==
            '[mytaskid: ########]: STARTED at processing job number 10022001'), '"%s" does not work.' % regEx
    print 'sub() with \'', regEx, '\': ', timeit('rr.sub(\'########\', s)', number=500000, setup='''
import re
s = '%s'
rr = re.compile('%s')
''' % (s, regEx)
    )
    print 'findall() with \'', regEx, '\': ', timeit('rr.findall(s)', setup='''
import re
s = '%s'
rr = re.compile('%s')
''' % (s, regEx)
    )

testIt('\\b[0-9a-z]*(?:[a-z][0-9]|[0-9][a-z])[0-9a-z]*\\b')
testIt('\\b[a-z\d]*(?:\d[a-z]|[a-z]\d)[a-z\d]*\\b')
testIt('\\b(?=[a-z0-9]*[0-9])[a-z0-9]*[a-z][a-z0-9]*\\b')
testIt('\\b(?=[0-9]*[a-z])(?=[a-z]*[0-9])[a-z0-9]+\\b')

制作:

sub() with ' \b[0-9a-z]*(?:[a-z][0-9]|[0-9][a-z])[0-9a-z]*\b ':  0.328042736387
findall() with ' \b[0-9a-z]*(?:[a-z][0-9]|[0-9][a-z])[0-9a-z]*\b ':  0.350668751542
sub() with ' \b[a-z\d]*(?:\d[a-z]|[a-z]\d)[a-z\d]*\b ':  0.314759661193
findall() with ' \b[a-z\d]*(?:\d[a-z]|[a-z]\d)[a-z\d]*\b ':  0.35618526928
sub() with ' \b(?=[a-z0-9]*[0-9])[a-z0-9]*[a-z][a-z0-9]*\b ':  0.322802906619
findall() with ' \b(?=[a-z0-9]*[0-9])[a-z0-9]*[a-z][a-z0-9]*\b ':  0.35330467656
sub() with ' \b(?=[0-9]*[a-z])(?=[a-z]*[0-9])[a-z0-9]+\b ':  0.320779061371
findall() with ' \b(?=[0-9]*[a-z])(?=[a-z]*[0-9])[a-z0-9]+\b ':  0.347522144274

最佳答案

尝试以下正则表达式:

\b[0-9a-z]*(?:[a-z][0-9]|[0-9][a-z])[0-9a-z]*\b

这将匹配包含数字后跟字母的单词,反之亦然。

因此它将涵盖一组完整的那些至少包含一个数字和一个字母的单词。

注意:虽然 python 不是这种情况,但我观察到并非所有工具都支持lookaheadlookbehind。所以我宁愿尽可能避免使用它们。

关于python - regEx:匹配两组字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19254974/

相关文章:

Python检查udp端口打开

python - 从python中的单独文件导入列表变量

python - 是否应避免使用 DataFrame 函数 groupBy?

python - 我如何用 Pygame 计算鼠标速度?

python - 如何将 CSV 文件直接发送到 FTP 服务器

regex - 如何使用ultraedit和正则表达式删除 "(2003)"等字符串中的括号?

regex - grep环顾四周比赛不工作

java - 字符串替换正则表达式仅在 [] 之外使用标记

regex - 使用 TRegEx 在 Delphi 中创建正则表达式

javascript - 使用 or 运算符匹配字符串的一部分