我有以下字符串:
a = 'P/2008 A3 (SOHO)'
我想将其更改为:
a = 'P/2008-A3-SOHO'
尝试解决问题:
第1步:
b = re.sub("\s", "-", a)
print b
输出:
P/2008-A3-(SOHO)
第2步:
c = re.sub("[\(\)]", "", b)
print c
输出:
P/2008-A3-SOHO
我得到了我需要的输出,但有没有更有效的方法呢?我想一步解决它。
答案 0 :(得分:5)
re.sub
不仅接受第二个参数的字符串,还接受一个函数。该函数将匹配对象作为参数获取,函数的返回值用作替换字符串:
>>> re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)
'P/2008-A3-SOHO'
顺便说一句,你不需要在角色类((
)内逃避)
,[...]
。
答案 1 :(得分:2)
您可以使用捕获组从输入中捕获特定字符串。
正则表达式:
^(\S+)\s*(\S+)\s*\(([^)]*)\)$
替换字符串:
\1-\2-\3
>>> import re
>>> a = 'P/2008 A3 (SOHO)'
>>> m = re.sub(r'^(\S+)\s*(\S+)\s*\(([^)]*)\)$', r'\1-\2-\3', a)
>>> m
'P/2008-A3-SOHO'
答案 2 :(得分:1)
falsetru提供了一个很好的答案,如何在单个"正则表达式操作中进行多次替换"。
我只想指出,由于可读性和效率的原因,单行并不总是更好。两个正则表达式比具有lambda
回调的单个正则表达式更快,我并且认为它们也更具可读性:
>>> import timeit
>>> setup = "import re; a = 'P/2008 A3 (SOHO) P/2008 A3 (SOHO)'"
>>> stmt1 = """re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)"""
>>> stmt1 = """r = re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)"""
>>> stmt2 = """r = re.sub("\s", "-", a)
... r = re.sub("[\(\)]", "", r)"""
>>> timeit.timeit(setup=setup, stmt=stmt1)
9.311270136909659
>>> timeit.timeit(setup=setup, stmt=stmt2)
7.7278099642134315
当我们事先编译正则表达式(并且,为了正义,定义函数而不是lambda
)时,这变得更加明显:
>>> setup = """import re
... a = 'P/2008 A3 (SOHO) P/2008 A3 (SOHO)'
... r1 = re.compile(r"[()\s]")
... r2 = re.compile(r"\s")
... r3 = re.compile(r"[()]")
... def f(m): return '-' if m.group().isspace() else ''
... """
>>> stmt1 = """r = r1.sub(f, a)"""
>>> timeit.timeit(setup=setup, stmt=stmt1)
7.351804295542024
>>> stmt2 = """r = r2.sub("-", a)
... r = r3.sub("", r)"""
>>> timeit.timeit(setup=setup, stmt=stmt2)
4.5631406412521756