2012-02-10 44 views
1

我有多行字符串,我想要替換,但不明白爲什麼它不起作用。出於某種原因,字符串中的句點會停止正則表達式的匹配。期間停止Python中的多線正則表達式替換?

我的字符串:

s = """ 
[some_previous_text] 
<start> 
one_period . 
<end> 
[some_text_after] 
""" 

想什麼我就結了:

s = """ 
[some_previous_text] 
foo 
[some_text_after] 
""" 

我最初嘗試,但它不匹配任何東西:

>>> import re 
>>> s = "<start>\none_period .\n<end>" 
>>> print re.sub("<start>[^.]*<end>", "foo", s) 
<start> 
one_period . 
<end> 

但是,當我把這段時間拿出來的時候,它工作的很好:

>>> import re 
>>> s = "<start>\nno_period\n<end>" 
>>> print re.sub("<start>[^.]*<end>", "foo", s) 
foo 

此外,當我把一個<end>標籤的期限之前,它匹配的第一個<end>標籤:

>>> import re 
>>> s = "<start>\n<end>\none_period .\n<end>" 
>>> print re.sub("<start>[^.]*<end>", "foo", s) 
foo 
one_period . 
<end> 

所以這是怎麼回事呢?爲什麼期間停止匹配[^.]*

編輯:

解決

我誤以爲克拉^是新線路匹配。我需要的是一個re.DOTALL標誌(如Amber所示)。下面是我現在正在使用的表達:

>>> import re 
>>> s = "<start>\none_period .\n<end>" 
>>> print re.sub("<start>.*<end>", "foo", s, flags=re.DOTALL) 
foo 

回答

3

爲什麼不呢? [^.]是「不是.」的所有字符的集合,因此不符合句點。


也許你不是打算只是把.*(任意數量的任何字符),而不是[^.]*

匹配跨換行符,指定re.DOTALL

re.sub("<start>.*<end>", "foo", s, flags=re.DOTALL) 
+0

如果我使用'。*',但它不匹配任何東西(即''''''''''''''''''什麼是正確的替代表達? – user749618 2012-02-10 21:51:49

+0

如果您希望'.'跨行匹配,您需要使用're.DOTALL'標誌。 http://docs.python.org/library/re.html#re。DOTALL – Amber 2012-02-10 21:53:31

+0

're.sub(「。* 」,「foo」,s,flags = re.DOTALL)'works!非常感謝。 – user749618 2012-02-10 21:54:32

1

那是因爲[^.]*是一個否定的字符類的任何字符但經過一段時間相匹配。

您可能想要一些類似<start>.*?<end>以及re.S修飾符,這使得點也匹配換行符。

re.sub("<start>.*?<end>", "foo", s, flags=re.S) 
+0

那麼,什麼是正確的表達式中使用? – user749618 2012-02-10 21:52:35

+0

@ user749618我更新了我的答案。 're.S'與Amber建議的're.DOTALL'相同。 – stema 2012-02-10 21:55:41

+0

請注意,re.sub()只接受Python 2.7或Python 3.1+中的flags參數,然後您需要使用標記集合編譯正則表達式或使用類似'[\ s \ S] *的東西? '而不是'。*?'。 – 2012-02-10 21:57:14