2015-11-22 2 views
2

У меня есть несколько строк, как это:Как эффективно удалить не-ASCII символы и цифры, но сохранить акцентированные символы ASCII

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 флаг от re, но я не знаю, что с этим не так, потому что он удаляет «óëé, ...». Это та же проблема с использованием string.printable. я не знаю, почему

ord('ë') 
235 

Учитывая, что в таблице ASCII ему присваивается 137. Результат, я бы ожидать, что-то вроде этого:

x = some_method(s) 
"awëerwq bròn 23x4 we we s mexicqué" 

Тогда, я хотел бы кодировать с не зависит от незафиксированной кодификации.

+0

Похоже, вы хотите, чтобы символы с символом 'ord (c) <256', но исключая символы типа' + 'и' ''. Вам может быть лучше с жестко закодированной строкой со всеми символами, которые вы хотите сохранить, а затем просто выполните «.» .join (c для c in s if c in okay_chars). – TigerhawkT3

+0

Извините, я неправильно понял вопрос. Вы хотите сохранить все символы, используемые в кодовой странице 437, а не ASCII, но выборочно удалять номера. '' '235, потому что это его значение в unicode. 137 - это значение на кодовой странице 437. –

+0

Подождите, если вы не хотите номера, как '23x4' сделать разрез? – TigerhawkT3

ответ

2

Вот способ, который может помочь (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é' 

Это захватывает имена Юникода символов в строке, и соответствует Charaters чьих имен начните с LATIN, DIGIT или SPACE.

Например, это будет соответствовать:

>>> unicodedata.name('S') 
'LATIN CAPITAL LETTER S' 

И это не так:

>>> unicodedata.name('م') 
'ARABIC LETTER MEEM' 

Я достаточно уверен, что латинские символы все имеют Юникода имена, начинающиеся с 'Latin', так что должен отфильтровать другие сценарии написания, сохраняя цифры и пробелы. Для пунктуации нет удобного однострочного лайнера, поэтому в этом примере восклицательные знаки и т. Д. Также отфильтровываются.

Вы можете предположительно фильтровать по кодовой точке, используя что-то вроде ord(c) < 0x250, хотя вы можете получить некоторые вещи, которых не ожидаете.Или, вы можете попробовать фильтровать по unicodedata.category. Тем не менее, категория «письмо» включает письма из большого количества скриптов, поэтому вы все равно получите некоторые из них: «م».

+0

Спасибо Сет ... Я однозначно добавил условный доход для хранения пробелов – Nacho

1

Я использовал флаг ASCII из re, но я не знаю, что в этом плохого, потому что он удаляет «óëé, ...».

Я думаю, что вы задаете свой вопрос неправильно. 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)) 
+0

Спасибо @ Мартин, ваш пост очень проницателен. Я последовал за предложением Сета и поддержал различия, которые вы указали. – Nacho