web-dev-qa-db-ja.com

Pythonを使用して非ASCII文字を削除し、ピリオドとスペースを残すにはどうすればよいですか?

.txtファイルを使用しています。非ASCII文字を含まないファイルのテキスト文字列が必要です。ただし、スペースとピリオドは残したいです。現在、私もそれらを削除しています。コードは次のとおりです。

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

スペースとピリオドを残すためにonlyascii()を変更するにはどうすればよいですか?それほど複雑ではないと思いますが、理解できません。

82
user1120342

次のように、 string.printable を使用して、印刷できない文字列からすべての文字をフィルタリングできます。

>>> s = "some\x00string. with\x15 funny characters"
>>> import string
>>> printable = set(string.printable)
>>> filter(lambda x: x in printable, s)
'somestring. with funny characters'

私のマシンのstring.printableには以下が含まれます:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c
160
jterrace

別のコーデックに変更する簡単な方法は、encode()またはdecode()を使用することです。あなたの場合、ASCIIに変換し、サポートされていないすべてのシンボルを無視します。たとえば、スウェーデン文字åはASCII文字ではありません。

    >>>s = u'Good bye in Swedish is Hej d\xe5'
    >>>s = s.encode('ascii',errors='ignore')
    >>>print s
    Good bye in Swedish is Hej d

編集:

Python3:str->バイト-> 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(逆順でデコードおよびエンコード)

>>> "hej d\xe5".decode("ascii", errors="ignore").encode()
'hej d'
75
Zweedeend

@artfulrobotによると、これはfilterやlambdaよりも速いはずです:

re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string) 

ここで他の例を参照してください http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244

23
Noam Manos

あなたの質問はあいまいです。最初の2つの文は、スペースと「ピリオド」が非ASCII文字であると信じていることを意味します。これは間違っています。 ord(char)<= 127などのすべての文字は、ASCII文字です。たとえば、関数はこれらの文字! "#$%&\ '()* +、-。/を除外しますが、[] {}などの他のいくつかを含みます。

後ろに戻り、少し考え、質問を編集して、Word ASCIIに言及せずに何をしようとしているのか、およびord(char)> = 128などの文字が無視できると思う理由を教えてください。また、どのバージョンのPythonですか?入力データのエンコーディングは何ですか?

コードは入力ファイル全体を単一の文字列として読み取るため、別の回答に対するコメント(「優れたソリューション」)は、データの改行を気にしないことを意味します。ファイルに次のような2行が含まれている場合:

this is line 1
this is line 2

結果は'this is line 1this is line 2'になります... ...本当に欲しいものですか?

より優れたソリューションには次のものが含まれます。

  1. onlyasciiよりも優れたフィルター関数の名前
  2. 引数を保持する場合、フィルター関数は単に真理値を返す必要があるという認識:

    def filter_func(char):
        return char == '\n' or 32 <= ord(char) <= 126
    # and later:
    filtered_data = filter(filter_func, data).lower()
    
7
John Machin

印刷可能なアスキー文字が必要な場合は、おそらく次のようにコードを修正する必要があります。

if ord(char) < 32 or ord(char) > 126: return ''

これはstring.printable(@jterraceからの回答)と同等です。ただし、リターンとタブ( '\ t'、 '\ n'、 '\ x0b'、 '\ x0c'および '\ r'がないことを除きます) )しかし、質問の範囲に対応していません

1
joaquin

次のコードを使用して、英語以外の文字を削除できます。

import re
str = "123456790 ABC#%? .(朱惠英)"
result = re.sub(r'[^\x00-\x7f]',r'', str)
print(result)

これは戻ります

123456790 ABC#%? 。()

1
Noha Elprince

Fluent Python(Ramalho)-を強くお勧めします。第2章に触発された理解力のある一筆書きのリスト2

onlyascii = ''.join([s for s in data if ord(s) < 127])
onlymatch = ''.join([s for s in data if s in
              'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'])
0
Matthew Dunn