1

我需要用不间断空格替换«статья 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())
4

1 回答 1

4

问题是您复制和粘贴错误。

这种模式有效:

'(стат.{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+)

区别很明显:第一个有一个\u0441转义序列,而第二个有一个普通的 ASCII c

于 2013-11-27T20:23:44.740 回答