python - 某些字符的正则表达式冲突 (ISO-8859-1 Windows-1252)

标签 python regex text ascii iso-8859-1

all - 我正在尝试对一堆科学数据执行正则表达式,将某些特殊符号转换为 ASCII 友好字符。例如,我想将 'µ'(UTF-8\xc2\xb5) 替换为字符串 'micro',将 '±' 替换为 '+/-'。我编写了一个 python 脚本来执行此操作,如下所示:

import re
def stripChars(string):
    outString = (re.sub(r'\xc2\xb5+','micro', string)) #Metric 'micro (10^-6)' (Greek 'mu') letter
    outString = (re.sub(r'\xc2\xb1+','+/-', outString)) #Scientific 'Plus-Minus' symbol
    return outString

但是,对于这两个特定字符,我得到了奇怪的结果。我深入研究了一下,看起来我正在遭受错误 described here 的困扰,其中某些字符出现错误,因为它们是 UTF 数据,被解释为 Windows-1252(或 ISO 8859-1)。

我 grep 了相关数据,发现它也在那里返回错误结果(例如,'µ' 显示为 'µ')但是,在同一数据集中的其他地方,存在相同符号的数据正确显示。这可能是由于最初收集数据的系统中存在错误。真正奇怪的是,我当前的代码似乎只捕获了不正确的版本,让正确的版本通过。

无论如何,我真的不知道如何进行。我需要能够提出一系列正则表达式替换,以捕获这些字符的正确和错误版本,但在这种情况下,正确版本的标识符失败了。

我必须承认,我对编程还很初级,除了最基本的正则表达式之外的任何东西对我来说仍然像黑魔法。这个问题似乎比我以前必须解决的任何问题都要棘手一些,这就是为什么我把它带到这里来让更多人关注它。

谢谢!

最佳答案

如果您的输入数据编码为 UTF-8,您的代码应该可以工作。这是一个 适合我的完整程序。它假设输入是 UTF-8 和 只是对原始字节进行操作,而不是与 Unicode 相互转换。 请注意,我从每个输入正则表达式的末尾删除了 +;那 会接受最后一个字符中的一个或多个,您可能 不是故意的。

import re

def stripChars(s):
    s = (re.sub(r'\xc2\xb5', 'micro', s)) # micro
    s = (re.sub(r'\xc2\xb1', '+/-', s)) # plus-or-minus
    return s

f_in = open('data')
f_out = open('output', 'w')

for line in f_in:
    print(type(line))
    line = stripChars(line)
    f_out.write(line)

如果您的数据以其他方式编码(请参见 this question 了解如何判断),此版本会更有用。你可以 指定输入和输出的任何编码。它解码为内部 读取时使用 Unicode,替换时使用 Unicode,然后编码 写作。

import codecs
import re

encoding_in = 'iso8859-1'
encoding_out = 'ascii'

def stripChars(s):
    s = (re.sub(u'\u00B5', 'micro', s)) # micro
    s = (re.sub(u'\u00B1', '+/-', s)) # plus-or-minus
    return s

f_in = codecs.open('data-8859', 'r', encoding_in)
f_out = codecs.open('output', 'w', encoding_out)

for uline in f_in:
    uline = stripChars(uline)
    f_out.write(uline)

请注意,如果它尝试写入非 ASCII 数据,它将引发异常 使用 ASCII 编码。避免这种情况的简单方法是只写 UTF-8,但是您可能不会注意到未捕获的字符。你可以捕获 异常并做一些优雅的事情。或者你可以让程序 崩溃并为您缺少的角色更新它。

关于python - 某些字符的正则表达式冲突 (ISO-8859-1 Windows-1252),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51396110/

相关文章:

java - 正则表达式定义两个允许的字符/数字列表

正则表达式 - 用其他字符 + 自己替换数字

C++ ifstream 不读取\n?

python - 将包含数学问题的文本文件转换为包含这些问题答案的文本文件

python - 教程中的 RNN 示例代码中的 "Variable weights already exists"

python - 在 ipython 笔记本中读取单元格内容

java - java.util.regex.Matcher::useAnchoringBounds 如何工作?

python - 为什么 Pycharm 不能运行相对导入的代码?

python - 为整个存储库动态创建测试文件模板

c# - 读写name值文本文件的简单方法