Python 如何使用regexp拆分字符串而不保留捕获组?
我想在Python 如何使用regexp拆分字符串而不保留捕获组?,python,regex,string,python-3.x,regex-group,Python,Regex,String,Python 3.x,Regex Group,我想在Python中使用带反向引用的正则表达式拆分文本 rexp = re.compile(r"([`]{1,})ABC\1") rexp.split("blahblah``ABC``blahblah") 我得到了['blahblah','blahblah','blahblah'],但预期['blahblah','blahblah']。 如何在不保留捕获组的情况下拆分字符串?来自文档: 如果模式中使用了捕获括号,那么模式中所有组的文本也将作为结果列表的一部分返回 由于您希望使用反向引用,您无法
Python
中使用带反向引用的正则表达式拆分文本
rexp = re.compile(r"([`]{1,})ABC\1")
rexp.split("blahblah``ABC``blahblah")
我得到了['blahblah','blahblah','blahblah']
,但预期['blahblah','blahblah']
。
如何在不保留捕获组的情况下拆分字符串?来自文档:
如果模式中使用了捕获括号,那么模式中所有组的文本也将作为结果列表的一部分返回
由于您希望使用反向引用,您无法避免第一个捕获组,但您可以将其余组设置为非捕获组,并对您的拆分进行后期处理,以获得您想要的内容,例如:
rexp = re.compile(r"([`]{1,})->\s*(?:\S+)\s*\|(?:.+?)<-\1")
rexp.split("blahblah``->Left|Right<-``blahblah")[0::2] # ['blahblah', 'blahblah']
从文件中:
如果模式中使用了捕获括号,那么模式中所有组的文本也将作为结果列表的一部分返回
由于您希望使用反向引用,您无法避免第一个捕获组,但您可以将其余组设置为非捕获组,并对您的拆分进行后期处理,以获得您想要的内容,例如:
rexp = re.compile(r"([`]{1,})->\s*(?:\S+)\s*\|(?:.+?)<-\1")
rexp.split("blahblah``->Left|Right<-``blahblah")[0::2] # ['blahblah', 'blahblah']
您可以先用唯一分隔符替换拆分模式,然后在此分隔符上拆分:
>>> s="blahblah``ABC``blahblah"
>>> delim="<-split->"
>>> re.split(delim, re.sub(r"([`]+)ABC\1", delim, s))
['blahblah', 'blahblah']
更新 显示这一点的时间与公认的答案一样快:
import re
def f1(s):
rexp = re.compile(r"([`]{1,})ABC\1")
return rexp.split(s)[0::2]
def f2(s):
delim="<-split->"
rexp1=re.compile(r"([`]+)ABC\1")
rexp2=re.compile(delim)
return rexp2.split(rexp1.sub(delim, s))
def f3(s):
delim="<-split->"
rexp=re.compile(r"([`]+)ABC\1")
return rexp.sub(delim, s).split(delim)
if __name__=='__main__':
import timeit
for case, x in (('small',1000),('med',10000),('large',1000000)):
s="blahblah``ABC``blahblah"*x
print("Case {}, {:,} x, All equal: {}".format(case,x,(f1(s)==f2(s)==f3(s))))
for f in (f1,f2,f3):
print(" {:^10s}{:.4f} secs".format(f.__name__, timeit.timeit("f(s)", setup="from __main__ import f, s", number=10)))
使用PyPy,按照我建议的方式进行操作会更快:
Case small, 1,000 x, All equal: True
f1 0.0020 secs
f2 0.0021 secs
f3 0.0012 secs
Case med, 10,000 x, All equal: True
f1 0.0325 secs
f2 0.0288 secs
f3 0.0217 secs
Case large, 1,000,000 x, All equal: True
f1 4.4900 secs
f2 3.0680 secs
f3 2.1079 secs
所以我不确定你所说的非常大的输入字符串是什么意思,这是一个可怕的成本…--计时显示,即使输入的字符串很大,它也一样或更快。您可以先用唯一的分隔符替换拆分模式,然后在此基础上拆分:
>>> s="blahblah``ABC``blahblah"
>>> delim="<-split->"
>>> re.split(delim, re.sub(r"([`]+)ABC\1", delim, s))
['blahblah', 'blahblah']
更新 显示这一点的时间与公认的答案一样快:
import re
def f1(s):
rexp = re.compile(r"([`]{1,})ABC\1")
return rexp.split(s)[0::2]
def f2(s):
delim="<-split->"
rexp1=re.compile(r"([`]+)ABC\1")
rexp2=re.compile(delim)
return rexp2.split(rexp1.sub(delim, s))
def f3(s):
delim="<-split->"
rexp=re.compile(r"([`]+)ABC\1")
return rexp.sub(delim, s).split(delim)
if __name__=='__main__':
import timeit
for case, x in (('small',1000),('med',10000),('large',1000000)):
s="blahblah``ABC``blahblah"*x
print("Case {}, {:,} x, All equal: {}".format(case,x,(f1(s)==f2(s)==f3(s))))
for f in (f1,f2,f3):
print(" {:^10s}{:.4f} secs".format(f.__name__, timeit.timeit("f(s)", setup="from __main__ import f, s", number=10)))
使用PyPy,按照我建议的方式进行操作会更快:
Case small, 1,000 x, All equal: True
f1 0.0020 secs
f2 0.0021 secs
f3 0.0012 secs
Case med, 10,000 x, All equal: True
f1 0.0325 secs
f2 0.0288 secs
f3 0.0217 secs
Case large, 1,000,000 x, All equal: True
f1 4.4900 secs
f2 3.0680 secs
f3 2.1079 secs
所以我不确定你所说的非常大的输入字符串是什么意思,这是一个可怕的成本…--计时显示,即使输入字符串很大,它也一样或更快。@GarbageCollector但由于反向引用,我不能使用非捕获组。@GarbageCollector但由于反向引用,我不能使用非捕获组。使其他非捕获组变得非常简单,谢谢!使其他组不捕获使此问题变得非常简单,谢谢!它不会比使用类似正则表达式的re.split更糟糕。见计时。。。在PyPy上,它非常快,不会比使用类似正则表达式的re.split更糟糕。见计时。。。在PyPy上,速度要快得多