python:使用regex re.sub将常规字符替换为unicode字符

python:使用regex re.sub将常规字符替换为unicode字符,python,regex,unicode,character-encoding,Python,Regex,Unicode,Character Encoding,我有一个让我发疯的简单问题,这似乎是由于python对unicode字符的处理 我在磁盘上存储了latex表(与非常类似),我想在其上应用一些正则表达式,以便连字符-(\u2212)被短划线-(alt 0150或\u2013)代替 我使用以下函数执行两个不同的regex和replace import re import glob def mychanger(fileName): with open(fileName,'r') as file: str = file.read()

我有一个让我发疯的简单问题,这似乎是由于python对
unicode
字符的处理

我在磁盘上存储了
latex
表(与非常类似),我想在其上应用一些正则表达式,以便连字符
-
\u2212
)被短划线
-
alt 0150
\u2013
)代替

我使用以下函数执行两个不同的regex和replace

import re
import glob

def mychanger(fileName):
  with open(fileName,'r') as file:
    str = file.read()
    str = str.decode("utf-8")
    str = re.sub(r"((?:^|[^{])\d+)\u2212(\d+[^}])","\\1\u2013\\2", str).encode("utf-8")
    str = re.sub(r"(^|[^0-9])\u2212(\d+)","\\1\u2013\\2", str).encode("utf-8")
  with open(fileName,'wb') as file:
    file.write(str)

myfile = glob.glob("C://*.tex")
for file in myfile: mychanger(file)  
不幸的是,这并没有改变任何事情

但是,如果我使用非unicode字符(如
$
)而不是
\u2013
),这意味着正则表达式代码是正确的,那么它是有效的

我在这里迷路了,我试着使用
re.sub(ur)((?:^[^{])\d+\u2212(\d+[^}]),“\\1\u2013\\2”,str).encode(“utf-8”)
,但它仍然没有改变任何东西


这里怎么了?谢谢

您的示例文件实际上包含
连字符减号(U+002D),而不是U+2212

即使它确实包含正确的字符,您也遇到了Python 2.x Unicode的所有n00b问题:

  • 内联解码和编码。事实上你编码了两次
  • 在非Unicode字符串中使用Unicode文字(
    \u2212
  • 不必要地使用
    r
    raw修饰符
  • 我的建议是删除所有解码和编码,并允许Python为您执行。
    io
    模块向后移植Python3.x行为并为您解码文件。我还将
    str
    重命名为
    my_str
    ,以避免与Python自己的
    str
    类冲突

    import re
    import glob
    import io
    
    def mychanger(fileName):
        with io.open(fileName,'r', encoding="utf-8") as file:
            my_str = file.read()
    
            my_str = re.sub(u"((?:^|[^{])\d+)\u002d(\d+[^}])", u"\\1\u2013\\2", my_str)
            my_str = re.sub(u"(^|[^0-9])\u002d(\d+)",          u"\\1\u2013\\2", my_str)
    
        with io.open(fileName, 'w', encoding="utf-8") as file:
            file.write(my_str)
    
    myfile = glob.glob(C://*.tex")
    
    for file in myfile: mychanger(file)
    

    有关Python 2.x和Unicode的详细说明,请参见

    Try:
    u“\\1\u2013\\2”
    Noobie,为什么要传递列表?您在此处发布的代码似乎不是您正在运行的代码。请仅在完成所有替换后尝试对字符串进行编码。Dash标点符号连字符减号是
    -
    \u002D
    )与MathSymbol减号
    \u2212
    )。Python 2.x或3.x?谢谢!有点道理我碰到了noobie问题你不觉得吗:在Python2中,当你复制粘贴代码时,DIt是不可避免的:)哦,当名称合适时;)