23
4

5 回答 5

11

那这个呢?它首先创建翻译表,但老实说,我认为没有它你就无法做到这一点。

transl_table = dict( [ (ord(x), ord(y)) for x,y in zip( u"‘’´“”–-",  u"'''\"\"--") ] ) 

with open( "a.txt", "w", encoding = "utf-8" ) as f_out : 
    a_str = u" ´funny single quotes´ long–-and–-short dashes ‘nice single quotes’ “nice double quotes”   "
    print( " a_str = " + a_str, file = f_out )

    fixed_str = a_str.translate( transl_table )
    print( " fixed_str = " + fixed_str, file = f_out  )

我无法将此打印运行到控制台(在 Windows 上),所以我不得不写入 txt 文件。
a.txt 文件中的输出如下所示:

a_str = '有趣的单引号' long–and–short dashes '漂亮的单引号' “漂亮的双引号” fixed_str = '有趣的单引号' long--and--short dashes '漂亮的单引号' “漂亮的双引号”

顺便说一句,上面的代码在 Python 3 中工作。如果你需要它用于 Python 2,它可能需要一些修复,因为在两个版本的语言中处理 Unicode 字符串的不同

于 2017-01-06T23:49:50.663 回答
9

没有这样的“正确”解决方案,因为对于任何给定的 Unicode 字符,都没有定义“ASCII 对应”。

例如,将看似简单的字符映射到 ASCII 单引号和双引号以及连字符。首先,让我们生成所有带有官方名称的 Unicode 字符。其次,让我们根据名称查找所有引号、连字符和破折号:

#!/usr/bin/env python3

import unicodedata

def unicode_character_name(char):
    try:
        return unicodedata.name(char)
    except ValueError:
        return None

# Generate all Unicode characters with their names
all_unicode_characters = []
for n in range(0, 0x10ffff):    # Unicode planes 0-16
    char = chr(n)               # Python 3
    #char = unichr(n)           # Python 2
    name = unicode_character_name(char)
    if name:
        all_unicode_characters.append((char, name))

# Find all Unicode quotation marks
print (' '.join([char for char, name in all_unicode_characters if 'QUOTATION MARK' in name]))
# " « » ‘ ’ ‚ ‛ “ ” „ ‟ ‹ › ❛ ❜ ❝ ❞ ❟ ❠ ❮ ❯ ⹂ 〝 〞 〟 "   

# Find all Unicode hyphens
print (' '.join([char for char, name in all_unicode_characters if 'HYPHEN' in name]))
# - ­ ֊ ᐀ ᠆ ‐ ‑ ‧ ⁃ ⸗ ⸚ ⹀ ゠ ﹣ - 

# Find all Unicode dashes
print (' '.join([char for char, name in all_unicode_characters if 'DASH' in name and 'DASHED' not in name]))
# ‒ – — ⁓ ⊝ ⑈ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ╌ ╍ ╎ ╏ ⤌ ⤍ ⤎ ⤏ ⤐ ⥪ ⥫ ⥬ ⥭ ⩜ ⩝ ⫘ ⫦ ⬷ ⸺ ⸻ ⹃ 〜 〰 ︱ ︲ ﹘ 

正如你所看到的,这个例子很简单,但有很多问题。Unicode 中有许多引号看起来不像 US-ASCII 中的引号,并且 Unicode 中有许多连字符看起来不像 US-ASCII 中的连字符减号。

还有很多问题。例如:

  • “SWUNG DASH” (⁓) 符号应该替换为 ASCII 连字符 (-) 还是波浪号 (~)?
  • “CANADIAN SYLLABICS HYPHEN” (᐀) 是否应替换为 ASCII 连字符 (-) 或等号 (=)?
  • 应该用 ASCII 引号 (")、撇号 (') 还是小于号 (<) 替换“单左点角引号”(‹)?

要建立“正确”的 ASCII 对应物,需要有人根据使用上下文回答这些问题。这就是为什么您的问题的所有解决方案都以一种或另一种方式基于映射字典。所有这些解决方案都会提供不同的结果。

于 2018-02-23T11:06:30.057 回答
4

您可以在unidecode包之上构建。

这非常慢,因为我们首先将所有 unicode 规范化为组合形式,然后尝试查看 unidecode 将其变成什么。如果我们匹配一个拉丁字母,那么我们实际上使用的是原始 NFC 字符。如果不是,那么我们会产生任何 degarbling unidecode 建议的内容。这只会留下强调的字母,但会转换其他所有内容。

import unidecode
import unicodedata
import re

def char_filter(string):
    latin = re.compile('[a-zA-Z]+')
    for char in unicodedata.normalize('NFC', string):
        decoded = unidecode.unidecode(char)
        if latin.match(decoded):
            yield char
        else:
            yield decoded

def clean_string(string):
    return "".join(char_filter(string))

print(clean_string(u"vis-à-vis “Beyoncé”’s naïve papier–mâché résumé"))
# prints vis-à-vis "Beyoncé"'s naïve papier-mâché résumé
于 2017-09-04T17:45:18.743 回答
1

您可以使用 str.translate() 方法(http://docs.python.org/library/stdtypes.html#str.translate)。但是,请阅读与 Unicode 相关的文档——翻译表有另一种形式:unicode 序数——> unicode 字符串(通常为 char)或 None。

好吧,但它需要字典。无论如何,您必须捕获替代品。如果没有任何表或数组,你想如何做到这一点?您可以将 str.replace() 用于单个字符,但这将是低效的。

于 2012-04-24T10:01:59.477 回答
-1

此工具将标准化 Markdown 中的标点符号:http: //johnmacfarlane.net/pandoc/README.html

-S, --smart 产生印刷正确的输出,将直引号转换为弯引号,--- 转换为 em-dashes,-- 转换为 en-dashes,以及 ... 转换为省略号。在某些缩写之后插入不间断空格,例如“先生”。(注:此选项仅在输入格式为markdown或textile时有效。当输入格式为texture或输出格式为latex或context时自动选择。)

它是haskell,所以你必须弄清楚接口。

于 2012-04-24T08:36:51.097 回答