2016-08-22 38 views
1

循環我有下面的代碼,我想while循環部分作品手工測試,那就是它應該替換任何字內部字符與*和離開邊境字符同時re.match

# manual testing 
    r = re.compile(r'(\w[*]*)(\w)(\w+)') 
    rtext = r.sub(r'\1*\3', 'mon texste') 
    print(rtext) 
    rtext = r.sub(r'\1*\3', rtext) 
    print(rtext) 
    rtext = r.sub(r'\1*\3', rtext) 
    print(rtext) 
    rtext = r.sub(r'\1*\3', rtext) 
    print(rtext) 
    rtext = r.sub(r'\1*\3', rtext) 
    print(rtext) 

    text = "mon test is here" 
    # Loop testing, :(it works once et doesn't iterate !!! 
    while(r.match(text) is not None): 
     print(text, type(r.match(text)))# just to check 
     text = r.sub(r'\1*\3',text) 
    print(text) 

回答

0

這裏你不需要循環,你可以使用一個簡單的正則表達式和3個捕獲組,並使用re.sub替換參數中的lambda用星號替換中間部分。

import re 
r2 = re.compile(r"\b(\w)(\w*)(\w)\b") 
res = r2.sub(lambda m: "{0}{1}{2}".format(m.group(1), "*"*len(m.group(2)), m.group(3)), 'mon texste') 

Python demo

圖案的詳細資料

  • \b - 領先的單詞邊界
  • (\w) - 第1組:領先字字符
  • (\w*) - 第2組:零或更多的字詞
  • (\w) - 組3:後行字炭
  • \b - 尾隨字邊界

替換:

  • "{0}{1}{2}".format() - 建立從3組
  • m.group(1)結果 - 的領先word char
  • "*"*len(m.group(2)) - * times第二組的長度
  • m.group(3) - 尾字字符
0

re.match只匹配字符串開頭的字符;您應該改用re.search(docs)

因此,將r.match的環路條件更改爲r.search

while(r.search(text) is not None): 
    text = r.sub(r'\1*\3',text) 
print(text) 

此代碼正常工作。

0

正如xmcp已經說了,你正在使用re.match,並總是試圖匹配字符串的開頭,所以你將不得不使用re.search代替。

請注意,循環會不經常地運行正則表達式。您可以通過存儲匹配對象然後在沒有正則表達式的情況下執行實際替換來改變它,例如,使用標準字符串處理:

m = r.search(text) 
while m: 
    inner = '*' * (m.end() - m.start() - 2) 
    text = text[:m.start() + 1] + inner + text[m.end() - 1:] 
    m = r.search(text) 

這使用匹配的索引來修補字符串。

您還可以使用一些向後看和向前看魔術尋找內心的字符一個正則表達式進行更換:

>>> text = 'mon test is here' 
>>> re.sub('(?<!^)(?<!\s)\w(?!\s|$)', '*', text) 
'm*n t**t is h**e' 
+0

感謝大家的幫助。 @poke我可以使用字符串和列表功能,但目標是使用正則表達式,我是完全新的。所以感謝你的正則表達式 – KKoku