我有一些字符串的格式是
lorem ipsum, dolor sit - amet, consectetur : adipiscing elit. Praesent vitae orc
我希望它在每个分离器的第一个实例中被拆分,以返回
['lorem ipsum',
'dolor sit',
'amet, consectetur',
'adipiscing elit. Praesent vitae orc']
现在我的输出是
['lorem ipsum',
'dolor sit',
'amet',
'consectetur ',
'adipiscing elit. Praesent vitae orc']
现在我使用的是re.split(', | - |: ', txt)
,但它会分离字符串中的所有实例。关于如何实现所需输出,有什么建议吗?
编辑:
我意识到我的问题不清楚,所以举个例子,如果字符串是
"abc: def: ijk, lmno: pqr - stu, wx"
输出应该是
["abc",
"def: ijk",
"lmno: pqr",
"stu, wxy"]
而不是
["abc",
"def",
"ijk",
"lmno",
"pqr",
"stu",
"wxy"]
如果所有分隔符必须至少出现一次,则可以使用4个捕获组,其中backreference与3个选项中的1个匹配,但已匹配的除外。
^(.*?)(, | - |: )(.*?)(?!2)(, | - |: )(.*?)(?!2|4)(, | - |: )(.*)
图案将与匹配
^
字符串开始(.*?)
组1,尽可能少地匹配(, | - |: )
组2,匹配任何列出的(.*?)
组3,尽可能少地匹配(?!2)
否定前瞻,断言右边的不是第2组中匹配的(从2个有效选项中选择一个((, | - |: )
组4,匹配任何列出的(.*?)
组5,尽可能少地匹配(?!2|4)
否定前瞻,断言右边的不是第2组或第4组中匹配的(选择剩下的唯一有效选项((, | - |: )
组6,匹配任何列出的(.*)
组7,尽可能匹配任何字符
Regex演示
例如
import re
regex = r"^(.*?)(, | - |: )(.*?)(?!2)(, | - |: )(.*?)(?!2|4)(, | - |: )(.*)"
test_str = ("lorem ipsum, dolor sit - amet , consectetur : adipiscing elit. Praesent vitae orcnn"
"abc: def: ijk, lmno: pqr - stu, wxnn")
matches = re.search(regex, test_str, re.MULTILINE)
if matches:
print(matches.group(1))
print(matches.group(3))
print(matches.group(5))
print(matches.group(7))
输出
lorem ipsum
dolor sit
amet , consectetur
adipiscing elit. Praesent vitae orc
参见Python demo1和demo2
只是想一想,不确定这是否是一个有价值的答案,但也许你可以使用regex
而不是re
模块来利用非固定宽度的负面后备功能。例如:
s*([,:-])(?<!1.*1)s*
在Python中:
import regex as re
string1 = "abc: def: ijk, lmno: pqr - stu, wx"
lst1 = re.sub(r's*([,:-])(?<!1.*1)s*', '|' , string1).split('|')
print(lst1)
结果:
['abc', 'def: ijk', 'lmno: pqr', 'stu, wx']
您可以使用一个计算替换的小类:
import re
text = "lorem ipsum, dolor sit - amet, consectetur : adipiscing elit. Praesent vitae orc"
# text = "abc: def: ijk, lmno: pqr - stu, wx"
rx = re.compile(r'[-,:]')
class Replacer:
def __init__(self, *args, **kwargs):
for key in args:
setattr(self, key, 0)
self.needle = kwargs.get("needle")
def __call__(self, match):
key = match.group(0)
setattr(self, key, getattr(self, key, 0) + 1)
cnt = getattr(self, key, 0)
return self.needle if cnt == 1 else key
rpl = Replacer("-", ",", ":", needle="#@#")
result = [item.strip() for item in re.split("#@#", rx.sub(rpl, text))]
print(result)
产生
['lorem ipsum', 'dolor sit', 'amet, consectetur', 'adipiscing elit. Praesent vitae orc']