2014-02-18 80 views
1

我試圖解決一個正則表達式的困惑,我很困惑。我想到了以下幾點:Python重新返回不匹配的行

import re 
import fileinput 

TEST_DATA = [ 
    "6", 
    "2 ", 
    "1 877 2638277 ", 
    "91-011-23413627" 
] 

for line in TEST_DATA: 
    print(
     re.sub(
      r'(\d{1,3})[- ](\d{2,3})[- ]+(\d{5,10})', 
      r'CountryCode=\1,LocalAreaCode=\2,Number=\3', 
      line)) 

給我這個:

CountryCode=1,LocalAreaCode=877,Number=2638277 
CountryCode=91,LocalAreaCode=011,Number=23413627 

,而不是我得到這個:

6 
2 
CountryCode=1,LocalAreaCode=877,Number=2638277 
CountryCode=91,LocalAreaCode=011,Number=23413627 

我不明白爲什麼不匹配的線正在打印。

回答

6

re.sub返回字符串,無論是否發生替換。從the documentation

返回通過用替換repl替換字符串中模式的最左邊非重疊事件而獲得的字符串。如果未找到該模式,則字符串將保持不變。

也許你可以先檢查一下match是否發生,然後再進行更換。

for line in TEST_DATA: 
    if re.match(my_pattern, line): 
     print(
      re.sub(
       r'(\d{1,3})[- ](\d{2,3})[- ]+(\d{5,10})', 
       r'CountryCode=\1,LocalAreaCode=\2,Number=\3', 
       line)) 
0

嘗試:

import re  

TEST_DATA = [ 
    "6", 
    "2 ", 
    "1 877 2638277 ", 
    "91-011-23413627" 
] 

pattern = r'(\d{1,3})[- ](\d{2,3})[- ]+(\d{5,10})' 
rep = r'CountryCode=\1,LocalAreaCode=\2,Number=\3' 

for line in TEST_DATA: 
    if re.match(pattern, line): 
     print re.sub(pattern,rep,line) 
2

我要告訴你,我真的很討厭re.sub。我不知道爲什麼,我沒有一個很好的解釋,但我避免它像瘟疫一樣。我甚至無法真正記得曾經使用過它效果差,我只是不喜歡它......

它不會產生您的預期輸出的原因是,re.sub將返回字符串,無論它是否匹配正則表達式。這有點像"Hello there".replace("foo","bar") - 只是因爲它沒有找到任何東西來替換並不意味着它會拋棄你的字符串。我會做什麼,而不是是這樣的:

pattern = r'(?P<country>\d{1,3})[- ](?P<area>\d{2,3})[- ]+(?P<number>\d{5,10})' 
text = r"CountryCode={country},LocalAreaCode={area},number={number}" 

for line in TEST_DATA: 
    match = re.match(pattern,line) 
    if not match: continue 
    print(text.format(**match.groupdict())) 
+1

我想的文檔細讀會告訴我,它只是返回字符串,如果它不匹配,但是這似乎是一個無緣無故的恨它。 – Amanda

+0

@Amanda我不需要太多的理由,介意你!我也避免了像鼠疫這樣的正則表達式。 –