我有几个这样的字符串:
s = u'awëerwq\u0645\u0631\u062d\u0628\u0627\u043c\u0438\u0440bròn 1990 23x4 + &23 \'we\' we\'s mexicqué'
s
"awëerwq مرحباмир bròn 1990 23x4 + &23 'we' we's mexicqué"
我找不到一种方法可以删除像'مرحباми'这样的不可打印的内容,但保留拉丁字符,例如'óé,......'。在我的情况下,数字(如'1990')也是不受欢迎的。我使用了来自ASCII
的{{1}}标记,但我不知道它有什么问题,因为它删除了'óëé,......'。使用re
也是同样的问题。
我不知道为什么
string.printable
鉴于ASCII表被分配了137.我期望的结果是这样的:
ord('ë')
235
然后,我想编码而不依赖于不固定的编码。
答案 0 :(得分:3)
这是一种可能有用的方法(Python 3.4):
import unicodedata
def remove_nonlatin(s):
s = (ch for ch in s
if unicodedata.name(ch).startswith(('LATIN', 'DIGIT', 'SPACE')))
return ''.join(s)
>>> s = 'awëerwq\u0645\u0631\u062d\u0628\u0627\u043c\u0438\u0440bròn 1990 23x4 + &23 \'we\' we\'s mexicqué'
>>> remove_nonlatin(s)
'awëerwqbròn 1990 23x4 23 we wes mexicqué'
这将获取字符串中字符的unicode名称,并匹配名称以LATIN,DIGIT或SPACE开头的字符。
例如,这将匹配:
>>> unicodedata.name('S')
'LATIN CAPITAL LETTER S'
这不会:
>>> unicodedata.name('م')
'ARABIC LETTER MEEM'
我有理由相信拉丁字符都有以'LATIN'开头的unicode名称,因此这应该过滤掉其他编写脚本,同时保留数字和空格。标点符号没有方便的单行,因此在此示例中,感叹号等也会被过滤掉。
你可以通过使用像ord(c) < 0x250
这样的东西按代码点进行过滤,尽管你可能会得到一些你不期望的东西。或者,您可以尝试按unicodedata.category
进行过滤。但是,“字母”类别包含来自许多脚本的字母,因此您仍然会得到其中一些:'م'。
答案 1 :(得分:1)
我使用了来自re的ASCII标志,但我不知道它有什么问题,因为它删除了'óëé,......'。
我认为你的问题是错误的。 ASCII中没有字符óëé
。看看这里看到所有ASCII字符的集合,看看它是如何基本的:
https://en.wikipedia.org/wiki/ASCII#ASCII_printable_code_chart
您使用的字符串似乎是Unicode,因为它可以同时支持“مرحباми”和“'óëé”。
在这种情况下,您可以使用
找到所需的字符范围http://jrgraphix.net/research/unicode_blocks.php
并且仅包含拉丁文字符(例如,这将过滤掉阿拉伯字符)。
以下是一个例子:
import re
s = u"مرحباми123"
# prints "123" by keeping all characters from the following ranges:
# 0020 — 007F Basic Latin
# 00A0 — 00FF Latin-1 Supplement
# 0100 — 017F Latin Extended-A
# 0180 — 024F Latin Extended-B
print ''.join(re.findall(ur'[\u0020-\u007F\u00A0-\u00FF\u0100-\u017F\u0180-\u024F]+', s))