文字列からすべての特殊文字、句読点、スペースを削除します


236

文字と数字のみを使用できるように、文字列からすべての特殊文字、句読点、スペースを削除する必要があります。

回答:


351

これは正規表現なしで行うことができます:

>>> string = "Special $#! characters   spaces 888323"
>>> ''.join(e for e in string if e.isalnum())
'Specialcharactersspaces888323'

使用できますstr.isalnum

S.isalnum() -> bool

Return True if all characters in S are alphanumeric
and there is at least one character in S, False otherwise.

正規表現の使用を主張する場合は、他のソリューションで問題ありません。ただし、正規表現を使用せずに実行できる場合は、それが最善の方法です。


7
経験則として正規表現を使用しない理由は何ですか?
Chris Dutrow、2012年

@ChrisDutrow正規表現は、Python文字列組み込み関数よりも遅い
Diego Navarro

これは、文字列がUnicodeの場合にのみ機能します。それ以外の場合は、「str」オブジェクトに「isalnum」「isnumeric」などの属性が含まれていないというメッセージが表示されます。
NeoJi 2016

10
@DiegoNavarroはそれが真実ではないことを除いて、私はisalnum()とregexの両方のバージョンをベンチマークしました、そしてregexは50-75%速いです
Francisco Couzo

2
さらに、「8ビット文字列の場合、このメソッドはロケールに依存します。」!したがって、正規表現の代替案は厳密に優れています!
Antti Haapala

232

以下は、文字でも数字でもない文字列に一致する正規表現です。

[^A-Za-z0-9]+

正規表現の置換を行うPythonコマンドを次に示します。

re.sub('[^A-Za-z0-9]+', '', mystring)

10
キス:シンプルにバカにして!これは、正規表現以外のソリューションよりも短く、はるかに読みやすく、同様に高速かもしれません。(ただし、+その効率を少し改善するために
量指定子

1
これにより、単語間のスペース、「素晴らしい場所」->「素晴らしい場所」も削除されます。それを避ける方法は?
Reihan_amn

5
:@Reihan_amn単純にそれがなると、正規表現にスペースを追加[^A-Za-z0-9 ]+
ostroon

1
@ andy-white答えの正規表現にスペースを追加していただけますか?スペースは特殊文字ではありません...
Ufos

3
これはáöñなどの他の言語の変更された文字では機能しないと思います。私は正しいですか?もしそうなら、それはそれのための正規表現でしょうか?
HuLu ViCa

50

より短い方法:

import re
cleanString = re.sub('\W+','', string )

単語と数字の間にスペースが必要な場合は、 ''を ''に置き換えます


3
ただし、_は\ wにあり、この質問のコンテキストでは特殊文字です。
kkurian 2016年

コンテキストによって異なります-下線は、ファイル名やその他の識別子に非常に役立ちます。これは、特殊文字ではなく、無害化されたスペースとして扱うためです。通常、この方法は自分で使用します。
エシェロン

1
r'\W+'-少し話題から外れています(そして非常に知識が豊富です)が、すべての正規表現パターンは生の文字列である
Bob Stein

2
この手順では、アンダースコア(_)を特殊文字として扱いません。
Ms. Sabbir Ahmed

30

これを見た後、最も短い時間で実行されるものを見つけることにより、提供された回答を拡張することに興味があったので、提案された回答のいくつかを調べて、timeit2つの例の文字列と照合しました。

  • string1 = 'Special $#! characters spaces 888323'
  • string2 = 'how much for the maple syrup? $20.99? That s ricidulous!!!'

例1

'.join(e for e in string if e.isalnum())

  • string1 -結果:10.7061979771
  • string2 -結果:7.78372597694

例2

import re re.sub('[^A-Za-z0-9]+', '', string)

  • string1 -結果:7.10785102844
  • string2 -結果:4.12814903259

例3

import re re.sub('\W+','', string)

  • string1 -結果:3.11899876595
  • string2 -結果:2.78014397621

上記の結果は、次の平均から返される最低の結果の積です。 repeat(3, 2000000)

例3は、例1の 3倍の速度になります。


@kkurian私の回答の冒頭を読んだ場合、これは以前に提案されたソリューションの比較にすぎません。元の回答についてコメントしたいかもしれません... stackoverflow.com/a/25183802/2560922
mbeacom

ああ、これでどこへ行くのか分かります。できた!
kkurian 2016年

1
大きなコーパスを扱う場合は、例3を考慮する必要があります。
HARSH NILESH PATHAK

有効です!注意していただきありがとうございます。
mbeacom

私の答えを比較できますか''.join([*filter(str.isalnum, string)])
グリジェシュチャウハン

22

Python 2. *

私はfilter(str.isalnum, string)うまくいくと思います

In [20]: filter(str.isalnum, 'string with special chars like !,#$% etcs.')
Out[20]: 'stringwithspecialcharslikeetcs'

Python 3. *

Python3では、filter( )関数は(上記のように文字列ではなく)反復可能なオブジェクトを返します。itertableから文字列を取得するには、後ろに結合する必要があります。

''.join(filter(str.isalnum, string)) 

またはlist、結合の使用を渡す(不明ですが、少し高速になる可能性があります

''.join([*filter(str.isalnum, string)])

注:Python 3.5[*args]以降からの有効な解凍


4
@Alexey正解。python3 mapではfilterreduce 代わりに反復可能なオブジェクトを返します。それでもPython3 + では、受け入れられた回答よりも''.join(filter(str.isalnum, string)) (またはjoin useでリストを渡すこと''.join([*filter(str.isalnum, string)]))を好み ます。
Grijesh Chauhan

少なくともを読んで''.join(filter(str.isalnum, string))、が改善されているかどうかはわかりませんfilter(str.isalnum, string)。これは本当にPythreenic(そう、あなたはそれを使うことができます)の方法ですか?
TheProletariat

1
@TheProletariatポイントは、Python-3ではPython-2とは異なり、引数の型ではなくイテレータを返すため、Python3では文字列を返さないだけfilter(str.isalnum, string)ですfilter( )。+
Grijesh Chauhan

@GrijeshChauhan、私はあなたの答えを更新してPython2とPython3の両方の推奨事項を含める必要があると思います。
mwfearnley

18
#!/usr/bin/python
import re

strs = "how much for the maple syrup? $20.99? That's ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!]',r'',strs)
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)
print nestr

さらに特殊文字を追加することができ、それは ''に置き換えられます。つまり、それらは削除されます。


16

他の誰もが正規表現を使用していたのとは異なり、私はそうではないすべての文字を除外しようとします代わりに、私はしたくないものを明示的に列挙すると、私が欲しいものを。

たとえば、「aからz」までの文字(大文字と小文字)と数字のみが必要な場合、他のすべてを除外します。

import re
s = re.sub(r"[^a-zA-Z0-9]","",s)

これは、「数字ではないすべての文字、または 'a〜z'または 'A〜Z'の範囲の文字を空の文字列に置き換える」ことを意味します。

実際、^正規表現の最初の場所に特殊文字を挿入すると、否定が発生します。

追加のヒント:結果も小文字にする必要がある場合は、大文字が見つからない限り、正規表現をさらに速く簡単にすることができます。

import re
s = re.sub(r"[^a-z0-9]","",s.lower())

9

正規表現を使用し、2to3対応のUnicode認識2.xコードが必要/必要であるとします。

>>> import re
>>> rx = re.compile(u'[\W_]+', re.UNICODE)
>>> data = u''.join(unichr(i) for i in range(256))
>>> rx.sub(u'', data)
u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\xaa\xb2 [snip] \xfe\xff'
>>>


6

最も一般的なアプローチは、すべての単一の文字を分類するunicodedataテーブルの「カテゴリ」を使用することです。たとえば、次のコードは、カテゴリに基づいて印刷可能な文字のみをフィルタリングします。

import unicodedata
# strip of crap characters (based on the Unicode database
# categorization:
# http://www.sql-und-xml.de/unicode-database/#kategorien

PRINTABLE = set(('Lu', 'Ll', 'Nd', 'Zs'))

def filter_non_printable(s):
    result = []
    ws_last = False
    for c in s:
        c = unicodedata.category(c) in PRINTABLE and c or u'#'
        result.append(c)
    return u''.join(result).replace(u'#', u' ')

関連するすべてのカテゴリについては、上記のURLをご覧ください。もちろん、句読点のカテゴリでフィルタリングすることもできます。


$各行の末尾に?
John Machin、2011

コピーと貼り付けの問題の場合は、修正する必要がありますか?
Olli

5

string.punctuationには次の文字が含まれています:

'! "#$%&\'()* +、-。/ :; <=>?@ [\] ^ _` {|}〜 '

translate関数とmaketrans関数を使用して、句読点を空の値にマッピングできます(置換)

import string

'This, is. A test!'.translate(str.maketrans('', '', string.punctuation))

出力:

'This is A test'

4

翻訳を使用:

import string

def clean(instr):
    return instr.translate(None, string.punctuation + ' ')

警告:ASCII文字列でのみ機能します。


バージョンの違い?私TypeError: translate() takes exactly one argument (2 given)はpy3.4で取得します
マットウィルキー2016年

1
import re
my_string = """Strings are amongst the most popular data types in Python. We can create the strings by enclosing characters in quotes. Python treats single quotes the 

二重引用符と同じです。 "" "

# if we need to count the word python that ends with or without ',' or '.' at end

count = 0
for i in text:
    if i.endswith("."):
        text[count] = re.sub("^([a-z]+)(.)?$", r"\1", i)
    count += 1
print("The count of Python : ", text.count("python"))

0
import re
abc = "askhnl#$%askdjalsdk"
ddd = abc.replace("#$%","")
print (ddd)

そしてあなたはあなたの結果を

'askhnlaskdjalsdk


4
お待ちください...インポートしましたreが、使用していません。あなたのreplace基準はこれだけ特定の文字列のために動作します。あなたの文字列が何であるabc = "askhnl#$%!askdjalsdk"か?#$%パターン以外には何も効かないと思います。それを調整したいかもしれ
ませ

0

句読点、数字、特殊文字を削除する

例:-

ここに画像の説明を入力してください

コード

combi['tidy_tweet'] = combi['tidy_tweet'].str.replace("[^a-zA-Z#]", " ") 

結果:- ここに画像の説明を入力してください

ありがとう:)


0

ドイツ語、スペイン語、デンマーク語、フランス語など、特殊文字を含む他の言語(ドイツ語の "Umlaute" üなどäö単に正規表現検索文字列にこれらを追加します):

ドイツ語の例:

re.sub('[^A-ZÜÖÄa-z0-9]+', '', mystring)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.