文字列にアルファベットの文字が含まれているかどうかを確認するにはどうすればよいですか?


82

文字列にアルファベットの文字が含まれているかどうかを確認するための最も純粋なPython実装は何ですか?

string_1 = "(555).555-5555"
string_2 = "(555) 555 - 5555 ext. 5555

どこにstring_1戻ってくるFalseことにアルファベットのない手紙を持っていないためとstring_2戻ってくるTrue手紙を持つために。


2
これは英語のa / zアルファベットのみに限定する必要がありますか?ドイツ語など、他のアルファベットの「特殊」文字を考慮に入れる必要がありますか?
コッチ2012年

Unicodeを受け取る可能性はありますか?それとも単なるASCIIローマ字ですか?
神戸ジョン2012年

良いタイミングです:)とにかく、Unicode文字を使用した文字列のテストについてサポートが必要な場合は、この同様の質問を確認してください。
神戸ジョン2012年

1
英語のa / zアルファベットのみ、プレーンなASCIIローマ字のみに限定:)
Justin Papez 2012年

回答:


123

正規表現は迅速なアプローチである必要があります。

re.search('[a-zA-Z]', the_string)

1
JBernadoに感謝します、これは私がやったことであり、私がしなければならないことに対して完璧に機能します。
Justin Papez 2012年

30
正規表現は確かに少しやり過ぎのようです。any(c.isalpha() for c in string_1)おいしくPythonicです。
ジョリーワット2015年

5
@Josephいいえ、違います。この正規表現は、式よりもはるかに読みやすくなっています。また、どういうisalpha意味ですか?Python2とPython3を比較すると、これはまったく異なる動作になります。中国語はアルファベットの一部ですか?そうでない場合は、Python 3(またはUnicode文字列の場合はPython 2!)のジェネレーターと盲目的に一致させています。あなたがしたい場合にPythonを、ここにあります:Simple is better than complex.。そして、上記のOPのコメントを確認してください。彼はローマ字のみを一致させたいと考えています。
JBernardo 2015年

1
ジョセフの答えは完全に読みやすく、追加のインポートよりも確かに速いと思います。さらに、re.searchの引数の順序を覚えておく必要はありません
ヒントン

11
他の誰かが戻り値が何であるか疑問に思っているMatch場合、一致するものがある場合、または一致しないNone場合はオブジェクトを取得します。したがって、これはif re.search(...パターンと互換性があります。
Srini 2017

74

どうですか:

>>> string_1 = "(555).555-5555"
>>> string_2 = "(555) 555 - 5555 ext. 5555"
>>> any(c.isalpha() for c in string_1)
False
>>> any(c.isalpha() for c in string_2)
True

set(string_1)、よりefficentこと?
Rik Poggi 2012年

1
@リック。それをテストする前にstring_1をセットに変換することを意味しますか?いいえ、それ以上効率的ではありません。これは、すべての文字を少なくとも1回処理することが保証されていますが、最初のfalseが発生すると、任意の関数が短絡(停止)すると思います。
神戸ジョン2012年

このコードは、文字ごとに関数呼び出しが必要なため、多少遅くなります。に変換するsetと、関数呼び出しが減るかどうかはわかりませんが、オーバーヘッドがいくらか追加されます。
JBernardo 2012年

2
@JBernardo:timeitは、コンパイルされた正規表現よりも約1桁遅く、コンパイルされていない正規表現よりも約66%長い時間しかかからないことを示唆しています。それは私の「正規表現が嫌い」の制限の範囲内です。
DSM

1
確かに:「(555).555-5555内線5555」* 1000を使用すると、短絡のために同等の速度に戻ります。私は正規表現を書くよりもPythonで書くほうがずっと好きです。正規表現は、些細なことでない限りデバッグが難しいと感じます。パフォーマンス要件で要求されない限り、明確なPythonの記述をあきらめるつもりはありません。
DSM

27

islower()文字列で使用して、(他の文字の中でも)小文字が含まれているかどうかを確認できます。orそれにisupper()もいくつかの大文字が含まれているかどうかをチェックします。

以下:文字列内の文字:テストはtrueを生成します

>>> z = "(555) 555 - 5555 ext. 5555"
>>> z.isupper() or z.islower()
True

以下:文字列に文字がありません:テストはfalseを生成します。

>>> z= "(555).555-5555"
>>> z.isupper() or z.islower()
False
>>> 

すべての文字が文字である場合にのみisalpha()返されるwhichと混同しTrueないでください。これは、必要なものではありません。

私は混合ケースをうまく処理できないので、Barmの答えは私のものをうまく完成させることに注意してください。


3
入力がすべての文字であるかどうかをテストするだけでなく、文字が含まれているかどうかをテストするのが好きです。
コーンビートル2017

はい@Cornbeetle、本当にのようなものは、それらの年の感謝をすべての後に質問に答える
ジャン=フランソワ・ファーブル

これを置くための非常に良い方法。効率的にはどうですか?正規表現よりも優れていますか?
PNV

Pythonループが含まれていないため、効率は良好です。コンパイルするいかなる正規表現がないので、初期化フェーズのために特別に、私は正規表現と比較しませんでしたが、私はそれがわずかに速いだと仮定
ジャン=フランソワ・ファーブル

13

@jean-françois-fabreからの回答が気に入りましたが、不完全です。
彼のアプローチは機能しますが、テキストに純粋に小文字または大文字が含まれている場合に限ります。

>>> text = "(555).555-5555 extA. 5555"
>>> text.islower()
False
>>> text.isupper()
False

より良いアプローチは、最初に文字列を大文字または小文字にしてからチェックすることです。

>>> string1 = "(555).555-5555 extA. 5555"
>>> string2 = '555 (234) - 123.32   21'

>>> string1.upper().isupper()
True
>>> string2.upper().isupper()
False


2

上記の各方法をテストして、特定の文字列にアルファベットが含まれているかどうかを確認し、標準的なコンピューターで文字列ごとの平均処理時間を調べました。

〜250 ns

import re

〜3 µs

re.search('[a-zA-Z]', string)

〜6 µs

any(c.isalpha() for c in string)

〜850 ns

string.upper().isupper()


主張されているのとは反対に、reのインポートにかかる時間はごくわずかであり、reを使用した検索には、比較的小さな文字列であってもisalpha()を繰り返す場合に比べて約半分の時間がかかります。 したがって、文字列が大きくカウントが大きい場合、reの方がはるかに効率的です。 ただし、文字列を大文字小文字に変換して大文字小文字をチェックする(つまり、upper()。isupper()またはlower()。islower()のいずれかここで優先されます。すべてのループで、re.search()よりも大幅に高速であり、追加のインポートも必要ありません。



1
さらに最適化するために正規表現をコンパイルすることもできます。alpha_regex = re.compile( '[a-zA-Z]')後でalpha_regex.search(string)
Behdad Forghani

言うまでもなく、isalpha()は多言語ではうまく機能しません。韓国語であると予想される文字列に英語の文字が含まれているかどうかを確認したかったので、これを探していました。isalpha()メソッドはすべての韓国語の文字列に対してTrueを返します。
チャン・ウー

0

さらにこれを行うこともできます

import re
string='24234ww'
val = re.search('[a-zA-Z]+',string) 
val[0].isalpha() # returns True if the variable is an alphabet
print(val[0]) # this will print the first instance of the matching value

また、変数valがNoneを返す場合にも注意してください。これは、検索で一致するものが見つからなかったことを意味します

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