Eu estou trabalhando com um arquivo .txt. Eu quero uma seqüência de texto do arquivo sem caracteres não-ASCII. No entanto, eu quero deixar espaços e pontos. Actualmente, eu estou tirando aqueles também. Aqui está o código:
def onlyascii(char):
if ord(char) < 48 or ord(char) > 127: return ""
else: return char
def get_my_string(file_path):
f=open(file_path,"r")
data=f.read()
f.close()
filtered_data=filter(onlyascii, data)
filtered_data = filtered_data.lower()
return filtered_data
Como devo modificar o onlyascii () para deixar espaços e pontos? Eu imagino que não é muito complicado, mas eu não consigo descobrir.
Respostas:
129 para resposta № 1Você pode filtrar todos os caracteres da string que não podem ser impressos usando string.printable, como isso:
>>> s = "somex00string. withx15 funny characters"
>>> import string
>>> printable = set(string.printable)
>>> filter(lambda x: x in printable, s)
"somestring. with funny characters"
string.printable na minha máquina contém:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&"()*+,-./:;<=>?@[\]^_`{|}~ tnrx0bx0c
56 para resposta № 2
Uma maneira fácil de mudar para um codec diferente é porusando encode () ou decode (). No seu caso, você deseja converter em ASCII e ignorar todos os símbolos que não são suportados. Por exemplo, a letra sueca å não é um caractere ASCII:
>>>s = u"Good bye in Swedish is Hej dxe5"
>>>s = s.encode("ascii",errors="ignore")
>>>print s
Good bye in Swedish is Hej d
Editar:
Python3: str -> bytes -> str
>>>"Hej då".encode("ascii", errors="ignore").decode()
"hej d"
Python2: unicode -> str -> unicode
>>> u"hej då".encode("ascii", errors="ignore").decode()
u"hej d"
Python2: str -> unicode -> str (decodifica e codifica em ordem reversa)
>>> "hej dxe5".decode("ascii", errors="ignore").encode()
"hej d"
15 para resposta № 3
De acordo com o @artfulrobot, isso deve ser mais rápido que o filtro e o lambda:
re.sub(r"[^x00-x7f]",r"", your-non-ascii-string)
Veja mais exemplos aqui http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244
7 para resposta № 4
Sua pergunta é ambígua; Os dois primeirossentenças juntas implicam que você acredita que espaço e "período" são caracteres não-ASCII. Isso está incorreto. Todos os caracteres, de modo que ord (char) <= 127 são caracteres ASCII. Por exemplo, sua função exclui esses caracteres! "# $% &" () * +, -. / Mas inclui vários outros, por exemplo, [] {}.
Por favor, volte atrás, pense um pouco e edite o seupergunta para nos dizer o que você está tentando fazer, sem mencionar a palavra ASCII, e por que você acha que chars tais que ord (char)> = 128 são ignoráveis. Também: qual versão do Python? Qual é a codificação dos seus dados de entrada?
Por favor, note que o seu código lê toda a entradaarquivo como uma única seqüência de caracteres, e seu comentário ("ótima solução") para outra resposta implica que você não se importa com novas linhas em seus dados. Se o arquivo contiver duas linhas como esta:
this is line 1
this is line 2
o resultado seria "this is line 1this is line 2"
... É isso o que você realmente quer?
Uma solução maior incluiria:
- um nome melhor para a função de filtro do que
onlyascii
reconhecimento de que uma função de filtro precisa apenas retornar um valor geral se o argumento for mantido:
def filter_func(char): return char == "n" or 32 <= ord(char) <= 126 # and later: filtered_data = filter(filter_func, data).lower()
1 para resposta № 5
Se você quiser caracteres ASCII imprimíveis, provavelmente deverá corrigir seu código para:
if ord(char) < 32 or ord(char) > 126: return ""
isto é equivalente, para string.printable
(resposta de @jterrace), exceto pela ausência de retornos e tabulações ("t", "n", "x0b", "x0c" e "r"), mas não corresponde ao intervalo da sua pergunta
0 para a resposta № 6
Trabalhando no meu caminho através do Fluent Python (Ramalho) - altamente recomendado. Listar um-ish-liners de compreensão inspirados no Capítulo 2:
onlyascii = "".join([s for s in data if ord(s) < 127])
onlymatch = "".join([s for s in data if s in
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"])