当前位置:  开发笔记 > 编程语言 > 正文

替换有时加倍的字符的单个实例

如何解决《替换有时加倍的字符的单个实例》经验,为你挑选了6个好方法。

我有一个字符串,每个字符由管道字符(包括"|"s本身)分隔,例如:

"f|u|n|n|y||b|o|y||a||c|a|t"

我想替换所有"|"不是"|"没有的东西,以获得结果:

"funny|boy|a|cat"

我尝试过使用mytext.replace("|", ""),但这会删除所有内容,并且会产生一个长话.



1> timgeb..:

这可以通过一个相对简单的正则表达式来实现,而不必链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跟随.


当格式改变为允许`-`字符时,此方法不会中断+1,这与当前最高投票的答案不同.

2> Bhargav Rao..:

使用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] 


这比编译正则表达式的正则表达式解决方案快5倍,"700 ns vs3.9μs"
Yep和可读性也很重要,更容易阅读列表组件或替换而不是正则表达式,当非正则表达式也更快时,它对于想要正则表达式没有多大意义

3> poke..:

您可以先用其他东西替换双管,以确保在移除单个管道后仍能识别它们.然后你将它们更换回管道:

>>> 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'


@hagello答案非常明确地列出了简单(和*非常有效和快速*解决方案)的问题,并且不仅建议使用安全的替换值,而且还显示其他两个没有这个问题的解决方案.我不知道这是如何使得答案仍然如此糟糕*总是*downvote甚至是适合的.一个downvote说答案有问题,但我不知道如何展示一个简单有效的解决方案,它的缺点,以及两个替代方案是错误的.

4> Kasramvd..:

您可以使用正向前瞻性正则表达式来替换后跟字母字符的点数:

>>> 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'


@PadraicCunningham是的,我添加了锚'$`.谢谢注意.

5> Nighthacks..:

使用正则表达式.

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



6> Avinash Raj..:

捕获组的另一个正则表达式选项.

>>> 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'

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有