2013-11-27 144 views
1

我需要用«non-breaking space»替換«статья1»,«статьи2»等所有正常空格的出現。下面 建設工作正常:爲什麼正則表達式不工作?

re.sub('(стат.{0,4}) (\d+)', r'\1 \2', text) # 'r' in repl is important, otherwise the word is not replaced correctly, at least for texts in Russian. 

不過,我不希望重複使用re.sub爲«статья»,然後«пункт»,隨後幾個月的名字,我想有正則表達式字典來表達和替換。這裏是我的代碼,但預期它不工作:'статья 1 статьи 2'應該像'статья(non-breaking space here)1 статьи(non-breaking space here)2'

import re 

text = 'статья 1 статьи 2' 
dic = {'(cтат.{0,4}) (\d+)' : r'\1 \2'} 


def replace(): 
    global text 
    final_text = '' 
    for i in dic: 
     new_text = re.sub(str(i), str(dic[i]), text) 
     text = new_text 
    return text 

print (replace()) 
+0

希望這是Python 3.x?如果沒有,你有多個問題。 – abarnert

+0

另外,你爲什麼要創建一個'final_text'變量,然後替換全局而不是使用它,然後返回全局? – abarnert

+0

另外,你想在正則表達式模式中使用'r'前綴,而不僅僅是替換模式。你碰巧在這裏逃避,因爲'\ d'恰好意味着Python中的'\\ d'',但你永遠不應該指望它。 – abarnert

回答

3

的問題是,你複製和粘貼錯誤。

這種模式的工作原理:

'(стат.{0,4}) (\d+)' 

這一個不:

'(cтат.{0,4}) (\d+)' 

爲什麼?因爲在第一個字符和你的搜索字符串中,第一個字符是U + 0441,一個西里爾文的小Es。但在第二個,它是一個U + 0063,一個拉丁小C.當然,這兩個看起來大多數字體相同,但它們不是同一個字符。


那麼,你怎麼知道?好吧,當我懷疑這個問題,這裏就是我所做的:

>>> a = '(стат.{0,4}) (\d+)' # copied and pasted from your working code 
>>> b = '(cтат.{0,4}) (\d+)' # copied and pasted from your broken code 
>>> print(a.encode('unicode-escape').decode('ascii')) 
(\u0441\u0442\u0430\u0442.{0,4}) (\\d+) 
>>> print(b.encode('unicode-escape').decode('ascii')) 
(c\u0442\u0430\u0442.{0,4}) (\\d+) 

而且差別是顯而易見的:第一個具有其中第二個有一個純ASCII c一個\u0441轉義序列。

+1

是的,這是真的!非常感謝! – user3036755

+0

我知道了,但是,代碼在GUI中無法正常工作,由於其他一些原因,我想... http://pastebin.com/vBnFuuyP – user3036755

+0

UPD:當然,我正在尋找«стат»。但我檢查的文本只包含«Стат»。再一次感謝你! – user3036755

相關問題