2017-07-16 43 views
4
正則表達式

考慮Python的片段:通過替換在Python

import re 
str = 'that that kitty is cute' 

# Anchor at beginning of string 
rgexp_start = r'^(.*) \1' 
print(re.sub(rgexp_start, r'\1', str))  

# Do NOT anchor at beginning of string 
rgexp = r'(.*) \1' 
print(re.sub(rgexp, r'\1', str)) 

此打印:

that kitty is cute 
thatkittyiscute 

爲什麼第二個正則表達式刪除所有空格?作爲一個額外的問題,考慮JavaScript片段:

var str = 'that that kitty is cute'; 
var rgexp_start = /^(.*) \1/; 
alert(str.replace(rgexp_start, '$1')); 

var rgexp = /(.*) \1/; 
alert(str.replace(rgexp, '$1')); 

其中給出了兩次:

that kitty is cute 

爲什麼是它的JavaScript從Python的不同之處的非常相同的正則表達式處理?

回答

2

Javascript的行爲是不同的,因爲你還沒有在Javascript正則表達式中打開globalg標誌(默認在python中打開)。

如果使用正則表達式一樣用g標誌爲:

var rgexp = /(.*) \1/g; 
console.log(str.replace(rgexp, '$1')); 

然後它會打印:

thatkittyiscute 

這是相同的行爲python

順便說一句,如果您使用此稍有不同的正則表達式:

(\S+) \1 

則總是更換後打印此即使沒有錨在你的第一個例子:

that kitty is cute 

\S+相匹配的一個或多個一個非空白字符。

+1

以上答案都非常具有啓發性。總結一下:'print(re.sub(r'(\ S +)\ 1',r'\ 1','那個小貓很可愛,小狗很好玩'))'print:'那個小貓是可愛的,小狗是嬉戲的。正則表達式'(\ S +)\ 1'可以說是支持正則表達式的文本編輯器中重複單詞位置的最簡單路徑。 –

+1

很遺憾,一個人不能打勾2個答案。我建議閱讀anubhava和COLDSPEED的答案,兩者都非常相關。 –

3

要回答你的第一個問題,re.sub將代替確切地說你通過的模式。

因此,r'^(.*) \1'的意思是,替換開頭的所有重複項。既然您已經指定匹配從頭開始,並且由於字符串只有一個開頭,唯一可以找到匹配和替換的是'^that that',所以就完成了。

In[]: 'that that kitty is cute' 

'^that that' -> 'that' 

Out[]: 'that kitty is cute' 

r'(.*) \1'的情況下,可以.*實際匹配0個或多個字符。這一點很重要,因爲現在正則表達式不再受限於開始。所以它做的是,除了'^that that'(其中第一個正則表達式也是這樣),它匹配'',然後空格,然後''再次,共3次。因此,它將用''替代' '(兩側各有一個''(空字符串)的空格)。

In[]: 'that that kitty is cute' 

'that that' -> 'that' 
' '   -> '' 
' '   -> '' 
' '   -> '' 

Out[]: 'thatkittyiscute' 

要回答你的第二個問題,不同的B/W蟒蛇和JS,由anubhava說明的是,在JS全球標誌不會被默認啓用;只有第一個替換髮生,留下字符串的其餘部分不變。