Python、文字列からすべての非アルファベット文字を削除します


93

私はPythonMapReduceワードカウントプログラムを書いています。問題は、データにアルファベット以外の文字がたくさん散らばっているということです。この投稿を見つけました。Pythonの文字列から英数字以外の文字をすべて削除します。これは、正規表現を使用した優れたソリューションを示していますが、実装方法がわかりません。

def mapfn(k, v):
    print v
    import re, string 
    pattern = re.compile('[\W_]+')
    v = pattern.match(v)
    print v
    for w in v.split():
        yield w, 1

ライブラリの使用方法reや、そのことについての正規表現すらわからないのではないかと思います。着信文字列(本の行)に正規表現パターンをv適切に適用して、英数字以外の文字を含まない改行を取得する方法がわかりません。

提案?


vは本の全行(特にmoby dick)であり、私は文字ごとではなく単語ごとに行きます。したがって、一部の単語の最後に「、」が付いている可能性があるため、「憤慨」は「憤慨」とマッピングされません。
kDecker 2014年


Lolx-私と同じ面接前の自宅での運動をしましたか?Moby Dickで最もよく使われる50の単語を見つけて、その頻度を報告します。私はC ++、IIRCでそれを行いました
Mawgは

1
@Mawgそれは私の学部生の「クラウドコンピューティング」クラスでの演習でした。
kDecker 2017

回答:


130

使用する re.sub

import re

regex = re.compile('[^a-zA-Z]')
#First parameter is the replacement, second parameter is your input string
regex.sub('', 'ab3d*E')
#Out: 'abdE'

または、特定の文字セットのみを削除したい場合(入力でアポストロフィを使用しても問題ない場合があるため...)

regex = re.compile('[,\.!?]') #etc.

うーん、私はそれをかなり追跡することができますが、スペースを除くすべての非英数字を削除するパターンはどうですか?
kDecker 2014年

1
コレクションクラスにスペースを追加するだけです。つまり^a-zA-Z 、ただの代わりに^a-zA-Z
limasxgoesto0 2014年

改行についても心配していない限り、その場合はa-zA-Z \n。両方を1つにまとめる正規表現を見つけようとしていますが、使用している\w\W、目的の動作が得られません。\nその場合は、追加する必要があるかもしれません。
limasxgoesto0 2014年

ああ、改行文字。私の問題がそこにあるところです、私は私の結果を与えられた結果と比較していました、そして私はまだ離れていました。それが私の問題だと思います!ありがとう//うーん、改行文字と同じ結果で試してみました。もう1つ欠けているものがあると思います。//Duhhh ...大文字と小文字... //助けてくれてありがとう、今は完璧に動作します!
kDecker 2014年

50

正規表現を使用したくない場合は、試してみてください

''.join([i for i in s if i.isalpha()])

どうすればこれに参加できますか?'' .join?sを印刷すると、フィルターオブジェクトのみが取得されます
PirateApp 2018

1
うわー、これは私が探していたものです。これは、漢字、ひらがな、カタカナなどを考慮に入れています。称賛
root1

34

re.sub()関数を使用して、次の文字を削除できます。

>>> import re
>>> re.sub("[^a-zA-Z]+", "", "ABC12abc345def")
'ABCabcdef'

re.sub(MATCH PATTERN、REPLACE STRING、STRING TO SEARCH)

  • "[^a-zA-Z]+" --a-zA-zではない文字のグループを探します。
  • "" -一致した文字を「」に置き換えます

これはまた、アクセント付きの文字を削除することに注意してください:ãâàáéèçõなど
ブラッド・アーレンス

19

試してみてください:

s = ''.join(filter(str.isalnum, s))

これにより、文字列からすべての文字が取得され、英数字のみが保持され、それらから文字列が作成されます。


2
この回答では、さらに多くの説明と関連ドキュメントへのリンクを使用できます。
pdoherty9 2620

4

最速の方法は正規表現です

#Try with regex first
t0 = timeit.timeit("""
s = r2.sub('', st)

""", setup = """
import re
r2 = re.compile(r'[^a-zA-Z0-9]', re.MULTILINE)
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)

#Try with join method on filter
t0 = timeit.timeit("""
s = ''.join(filter(str.isalnum, st))

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""",
number = 1000000)
print(t0)

#Try with only join
t0 = timeit.timeit("""
s = ''.join(c for c in st if c.isalnum())

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)


2.6002226710006653 Method 1 Regex
5.739747313000407 Method 2 Filter + Join
6.540099570000166 Method 3 Join

0

特定のUnicodeプロパティクラスを照合する場合は、PyPiregexモジュールを使用することをお勧めします。このライブラリは、特に大きなテキストを処理する場合に、より安定していることも証明されており、さまざまなPythonバージョン間で一貫した結果が得られます。あなたがする必要があるのはそれを最新に保つことです。

pip intall regexまたはを使用してpip3 install regex)インストールする場合は、

import regex
print ( regex.sub(r'\P{L}+', '', 'ABCŁąć1-2!Абв3§4“5def”') )
// => ABCŁąćАбвdef

Unicode文字以外の1文字以上のすべてのチャンクをから削除しtextます。オンラインのPythonデモをご覧ください。"".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”'))同じ結果を得るために使用することもできます。

Pythonreでは、任意のUnicode文字に一致させるために、[^\W\d_]構成を使用できます(任意のUnicode文字に一致しますか?)。

したがって、文字以外のすべての文字を削除するには、すべての文字を照合して結果を結合することができます。

result = "".join(re.findall(r'[^\W\d_]', text))

または、[^\W\d_]:に一致する文字以外のすべての文字を削除します。

result = re.sub(r'([^\W\d_])|.', r'\1', text, re.DOTALL)

オンライン正規表現デモを参照してください。ただし、Unicode標準が進化しているため、さまざまなPythonバージョン間で一貫性のない結果が得られる可能性があり、一致する文字のセットは\wPythonバージョンによって異なります。regex一貫した結果を得るには、PyPiライブラリを使用することを強くお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.