在多行字符串中删除指定模式之前的所有字符

3 投票
5 回答
4349 浏览
提问于 2025-04-15 21:43

我想用Python删除一个多行字符串中,直到第一次出现某个特定模式的所有字符。在Perl中,可以用正则表达式来做到这一点,像这样:

#remove all chars up to first occurrence of cat or dog or rat
$pattern = 'cat|dog|rat' 
$pagetext =~ s/(.*?)($pattern)/$2/xms; 

那么在Python中,最好的方法是什么呢?

5 个回答

2

不使用正则表达式的方法

>>> s='hello cat!'
>>> pat=['cat','dog','rat']
>>> for n,i in enumerate(pat):
...     m=s.find(i)
...     if m != -1: print s[m:]
...
cat!
5
>>> import re
>>> s = 'hello cat!'
>>> m = re.search('cat|dog|rat', s)
>>> s[m.start():]
'cat!'
>>> import re
>>> s = 'hello cat!'
>>> p = 'cat|dog|rat'
>>> re.sub('.*?(?=%s)' % p, '', s, 1)
'cat!'

当然,你需要考虑到在实际解决方案中没有匹配的情况。

或者,更简单明了地说:

对于多行文本,使用 re.DOTALL 这个标志。

4

你想要删除某个模式第一次出现之前的所有字符;举个例子,你给出的字符串是 "cat|dog|rat"。

下面的代码可以用 re 来实现这个功能:

re.sub("(?s).*?(cat|dog|rat)", "\\1", input_text, 1)

或者,如果你还会再次使用这个正则表达式:

rex= re.compile("(?s).*?(cat|dog|rat)")
result= rex.sub("\\1", input_text, 1)

注意这里的非贪婪模式 .*?。最开始的 (?s) 允许匹配换行符,这样在匹配单词之前也能处理换行。

举个例子:

>>> input_text= "I have a dog and a cat"
>>> re.sub(".*?(cat|dog|rat)", "\\1", input_text, 1)
'dog and a cat'

>>> re.sub("(?s).*?(cat|dog|rat)", "\\1", input_text, 1)
'I have no animals!'

>>> input_text= "This is irrational"
>>> re.sub("(?s).*?(cat|dog|rat)", "\\1", input_text, 1)
'rational'

如果你只想对单词 cat、dog 和 rat 进行转换,你需要把正则表达式改成:

>>> re.sub(r"(?s).*?\b(cat|dog|rat)\b", "\\1", input_text, 1)
'This is irrational'

撰写回答