Python:用它们的ascii对应物替换印刷引号,破折号等

Thi*_*ter 12 python string

在我的网站上,人们可以发布新闻,不少编辑使用MS word和类似的工具来编写文本,然后复制并粘贴到我网站的编辑器中(简单的textarea,没有WYSIWYG等).

这些文本通常包含"漂亮"的引号,而不是简单的ascii(").它们有时也包含那些较长的破折号而不是-.

现在我想用他们的ascii对应物替换所有这些角色.但是,我不想删除变音符号和其他非ascii字符.我也非常喜欢使用一个不需要为所有这些字符创建映射字典的正确解决方案.

我的所有字符串都是unicode对象.

Mat*_*teo 9

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

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  )
Run Code Online (Sandbox Code Playgroud)

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

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

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


And*_*kha 8

没有这样“正确”的解决方案,因为对于任何给定的 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]))
# ? – — ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 
Run Code Online (Sandbox Code Playgroud)

如您所见,尽管这个例子很简单,但问题很多。Unicode 中有许多引号看起来不像 US-ASCII 中的引号,Unicode 中有许多连字符看起来不像 US-ASCII 中的连字符减号。

还有很多问题。例如:

  • “SWUNG DASH” (?) 符号是否应该替换为 ASCII 连字符 (-) 或波浪号 (~)?
  • “加拿大音节连字符” (?) 是否应该替换为 ASCII 连字符 (-) 或等号 (=)?
  • 是否应该用 ASCII 引号 (")、撇号 (') 或小于号 (<) 替换“单左指向角引号”(‹)?

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


Ric*_*h L 7

您可以在unidecode包之上进行构建。

\n\n

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

\n\n
import unidecode\nimport unicodedata\nimport re\n\ndef char_filter(string):\n    latin = re.compile(\'[a-zA-Z]+\')\n    for char in unicodedata.normalize(\'NFC\', string):\n        decoded = unidecode.unidecode(char)\n        if latin.match(decoded):\n            yield char\n        else:\n            yield decoded\n\ndef clean_string(string):\n    return "".join(char_filter(string))\n\nprint(clean_string(u"vis-\xc3\xa0-vis \xe2\x80\x9cBeyonc\xc3\xa9\xe2\x80\x9d\xe2\x80\x99s na\xc3\xafve papier\xe2\x80\x93m\xc3\xa2ch\xc3\xa9 r\xc3\xa9sum\xc3\xa9"))\n# prints vis-\xc3\xa0-vis "Beyonc\xc3\xa9"\'s na\xc3\xafve papier-m\xc3\xa2ch\xc3\xa9 r\xc3\xa9sum\xc3\xa9\n
Run Code Online (Sandbox Code Playgroud)\n


Mar*_*cin 0

该工具将规范 Markdown 中的标点符号:http ://johnmacfarlane.net/pandoc/README.html

\n\n
\n

-S, --smart 生成印刷正确的输出,将直引号转换为弯引号, --- 转换为长破折号, -- 转换为短破折号,\n 和 ... 转换为省略号。在某些缩写后面插入不间断空格,例如 \xe2\x80\x9cMr.\xe2\x80\x9d (注意:此选项仅在输入格式为 Markdown 或 Textile 时有效。自动选择\n当输入格式为 Textile 或输出格式为\n Latex 或 context 时。)

\n
\n\n

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

\n