我有一个字符串,每个字符由管道字符(包括"|"
s本身)分隔,例如:
"f|u|n|n|y||b|o|y||a||c|a|t"
我想替换所有"|"
不是"|"
没有的东西,以获得结果:
"funny|boy|a|cat"
我尝试过使用mytext.replace("|", "")
,但这会删除所有内容,并且会产生一个长话.
这可以通过一个相对简单的正则表达式来实现,而不必链str.replace
:
>>> import re >>> s = "f|u|n|n|y||b|o|y||a||c|a|t" >>> re.sub('\|(?!\|)' , '', s) 'funny|boy|a|cat'
说明:\ |(?!\ |)将查找|
未跟随另一个|
字符的字符.(?!foo)意味着负向前瞻,确保你所匹配的任何内容都不会被foo跟随.
使用sentinel值
替换||
的~
.这会记住||
.然后删除|
s.最后用它重新替换它们|
.
>>> s = "f|u|n|n|y||b|o|y||a||c|a|t" >>> s.replace('||','~').replace('|','').replace('~','|') 'funny|boy|a|cat'
另一种更好的方法是使用它们几乎是替代文本的事实.解决方案是让它们完全交替......
s.replace('||','|||')[::2]
您可以先用其他东西替换双管,以确保在移除单个管道后仍能识别它们.然后你将它们更换回管道:
>>> t = "f|u|n|n|y||b|o|y||a||c|a|t" >>> t.replace('||', '|-|').replace('|', '').replace('-', '|') 'funny|boy|a|cat'
您应该尝试选择一个安全临时值的替换值,并且不会自然地出现在您的文本中.否则,即使它最初不是双管,您也会遇到替换该字符的冲突.因此,如果您的文字可能包含短划线,请不要使用上述短划线.您也可以一次使用多个字符,例如:'
.
如果你想完全避免这种冲突,你也可以解决这个完全不同的问题.例如,您可以先通过双管道拆分字符串,然后对每个子字符串执行替换,最终将它们连接在一起:
>>> '|'.join([s.replace('|', '') for s in t.split('||')]) 'funny|boy|a|cat'
当然,您也可以使用正则表达式来替换那些未跟随另一个管道的管道:
>>> import re >>> re.sub('\|(?!\|)', '', t) 'funny|boy|a|cat'
您可以使用正向前瞻性正则表达式来替换后跟字母字符的点数:
>>> import re >>> st = "f|u|n|n|y||b|o|y||a||c|a|t" >>> re.sub(r'\|(?=[a-z]|$)',r'',st) 'funny|boy|a|cat'
使用正则表达式.
import re line = "f|u|n|n|y||b|o|y||a||c|a|t" line = re.sub("(?!\|\|)(\|)", "", line) print(line)
输出:
funny|boy|a|cat
捕获组的另一个正则表达式选项.
>>> import re >>> re.sub(r'\|(\|?)', r'\1', "f|u|n|n|y||b|o|y||a||c|a|t") 'funny|boy|a|cat'
说明:
\|
- 匹配所有管道字符.
(\|?)
- 如果存在,则捕获以下管道字符.然后替换匹配\1
将为您带来第一个捕获组的内容.因此,在单个点的位置,它将给出一个空字符串,并且||
,它将带来第二个管道字符.
通过单词和非单词边界的另一个技巧......
>>> re.sub(r'\b\|\b|\b\|\B', '', "f|u|n|n|y||b|o|y||a||c|a|t|") 'funny|boy|a|cat'
还有一个使用负面的背后..
>>> re.sub(r'(?奖金...
>>> re.sub(r'\|(\|)|\|', lambda m: m.group(1) if m.group(1) else '', "f|u|n|n|y||b|o|y||a||c|a|t") 'funny|boy|a|cat'