Pythonの研究ノート、特別な記録、あなたと共有してください、私はそれが皆に役立つことを願っています。
正規表現
文字列はプログラミングで最も頻繁に関与するデータ構造であり、文字列を操作する必要性はほとんどどこにでもあります。たとえば、文字列が正当な電子メールアドレスであるかどうかを判断するには、@の前後の部分文字列をプログラムで抽出して、それが単語とドメイン名であるかどうかを判断することは可能ですが、これは面倒なだけでなく、面倒でもあります。コードを再利用するのは難しい。
正規表現は、文字列を照合するための強力な武器です。その設計思想は、記述言語を使用して文字列のルールを定義することです。ルールに準拠する文字列はすべて「一致」すると見なされます。それ以外の場合、文字列は不正です。
したがって、文字列が有効な電子メールであるかどうかを判断する方法は次のとおりです。
-
電子メールに一致する正規表現を作成します。
-
正規表現を使用してユーザーの入力と一致させ、それが正当かどうかを判断します。
正規表現も文字列で表されるため、最初に文字を使用して文字を記述する方法を理解する必要があります。
正規表現では、文字を直接指定すると完全一致になります。数字に一致させるには\ dを使用し、文字または数字に一致させるには\ wを使用します。
- '00 \ d 'は' 007 'と一致できますが、' 00A 'と一致できません。
- '\ d \ d \ d'は '010'と一致できます。
- '\ w \ w \ d'は 'py3'と一致できます。
。任意の文字に一致する可能性があるため、次のようになります。
- 「py。」は「pyc」、「pyo」、「py!」などと一致します。
可変長文字を照合するには、正規表現で*を使用して任意の数の文字(0を含む)を表し、+を使用して少なくとも1文字を表し、?を使用して0または1文字を表し、{n}を使用して表すn文字、{n、m}を使用してnm文字を表します:
複雑な例を見てみましょう:\ d {3} \ s + \ d {3,8}。
左から右に読んでみましょう:
- \ d {3}は、「010」などの3つの数字に一致することを意味します。
- \ sはスペースに一致する可能性があるため(Tabなどの空白文字も含まれます)、\ s +は、少なくとも1つのスペースがあることを意味します。たとえば、 ''、 ''などに一致します。
- \ d {3,8}は、「1234567」などの3〜8個の数字を意味します。
まとめると、上記の正規表現は、電話番号を任意の数のスペースで区切られた市外局番と一致させることができます。
'010-12345'のような番号に一致させたい場合はどうなりますか?'-'は特殊文字であるため、正規表現では、エスケープするために ''を使用する必要があります。したがって、上記の正規表現は\ d {3}-\ d {3,8}です。
ただし、スペースが原因で「010-12345」と一致することはできません。したがって、より複雑なマッチング方法が必要です。
高度な
より正確に一致させるには、[]を使用して範囲を示します。次に例を示します。
- [0-9a-zA-Z_]は、数字、文字、またはアンダースコアに一致させることができます。
- [0-9a-zA-Z _] +は、「a100」、「0_Z」、「Py3000」など、少なくとも1つの数字、文字、またはアンダースコアで構成される文字列と一致します。
- [a-zA-Z _] [0-9a-zA-Z _] *は、文字またはアンダースコアで始まり、その後に、有効なPython変数である数字、文字、またはアンダースコアで構成される任意の文字列が続く場合に一致します。
- [a-zA-Z _] [0-9a-zA-Z_] {0、19}は、変数の長さをより正確に1〜20文字に制限します(前面に1文字、背面に最大19文字)。
A | BはAまたはBと一致する可能性があるため、(P | p)ythonは「Python」または「python」と一致する可能性があります。
行の先頭を示し、 \ dは数字で始まる必要があることを示します。
KaTeX解析エラー:未定義の制御シーケンス:位置8の\ d:行の終わりを示し、\ ̲d̲は数字で終わる必要があることを示します。
pyも「python」に一致する可能性があることに気付いたかもしれませんが、^ py $を追加すると、「py」にのみ一致する行全体の一致になります。
再モジュール
準備の知識があれば、Pythonで正規表現を使用できます。Pythonは、すべての正規表現関数を含むreモジュールを提供します。Python文字列自体も\でエスケープされるため、次の点に特に注意してください。
s = 'ABC\\-001' # Python的字符串
# 对应的正则表达式字符串变成:
# 'ABC\-001'
したがって、Pythonのrプレフィックスを使用することを強くお勧めします。そうすれば、エスケープについて心配する必要はありません。
s = r'ABC\-001' # Python的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'
まず、正規表現が一致するかどうかを判断する方法を確認します。
import re
re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
re.match(r'^\d{3}\-\d{3,8}$', '010 12345')
match()メソッドは、一致するかどうかを判断します。一致が成功した場合は、Matchオブジェクトを返します。それ以外の場合は、Noneを返します。一般的な判断方法は次のとおりです。
test = '用户输入的字符串'
if re.match(r'正则表达式', test):
print('ok')
else:
print('failed')
分割文字列
正規表現を使用して文字列を分割する方が、固定文字を使用するよりも柔軟性があります。通常の分割コードを参照してください。
'a b c'.split(' ')
['a', 'b', '', '', 'c']
連続したスペースは認識できません。正規表現を使用してみてください。
re.split(r'\s+', 'a b c')
['a', 'b', 'c']
スペースがいくつあっても、普通に分割できます。参加してみてください:
re.split(r'[\s\,]+', 'a,b, c d')
['a', 'b', 'c', 'd']
もう一度参加してください:試してください:
re.split(r'[\s\,\;]+', 'a,b;; c d')
['a', 'b', 'c', 'd']
ユーザーがタグのセットを入力した場合は、次回、正規表現を使用して不規則な入力を正しい配列に変換することを忘れないでください。
グループ化
正規表現には、単に一致するかどうかを判断するだけでなく、部分文字列を抽出する強力な機能もあります。()を使用して、抽出するグループを示します。といった:
^(\ d {3})-(\ d {3,8})$は、それぞれ2つのグループを定義し、一致した文字列から市外局番と市内番号を直接抽出できます。
import re
m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
print m
print m.group(0)
print m.group(1)
print m.group(2)
演算結果:
<_sre.SRE_Match object at 0x100249360>
010-12345
010
12345
Process finished with exit code 0
正規表現でグループが定義されている場合、Matchオブジェクトのgroup()メソッドを使用して部分文字列を抽出できます。
group(0)は常に元の文字列であり、group(1)、group(2)...は1、2、...の部分文字列を表すことに注意してください。
部分文字列の抽出は非常に便利です。もっと残忍な例を見てみましょう:
t = '19:05:30'
m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)
print m.groups()
演算結果:
('19', '05', '30')
Process finished with exit code 0
この正規表現は、法定時間を直接識別できます。ただし、日付の識別など、正規表現を使用して検証を完了できない場合があります。
'^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$'
「2-30」や「4-31」などの違法な日付については、まだ通常のルールで認識されていないか、書き出すのが非常に難しいので、現時点では、プログラムは認識に協力する必要があります。
欲張りマッチ
最後に、通常のマッチングはデフォルトで貪欲なマッチング、つまりできるだけ多くの文字をマッチングすることを指摘することが重要です。例は次のとおりで、番号の後の0に一致します。
print re.match(r'^(\d+)(0*)$', '102300').groups()
演算結果:
('102300', '')
Process finished with exit code 0
\ d +は貪欲なマッチングを採用しているため、次のすべての0に直接一致します。その結果、0 *は空の文字列にのみ一致します。
\ d +に非貪欲なマッチングを使用させる(つまり、可能な限り一致させない)ようにして、次の0に一致させ、?を追加する必要があります。\ d +に非貪欲なマッチングを使用させるには、次のようにします。
print re.match(r'^(\d+?)(0*)$', '102300').groups()
演算結果:
('1023', '00')
Process finished with exit code 0
コンパイル
Pythonで正規表現を使用する場合、reモジュールは内部で2つのことを行います。
- 正規表現をコンパイルします。正規表現自体の文字列が不正な場合、エラーが報告されます。
- コンパイルされた正規表現を使用して、文字列と一致させます。
正規表現を何千回も再利用する場合は、効率上の理由から、正規表現を事前にコンパイルできます。再利用する場合は、この手順をコンパイルして直接一致させる必要はありません。
import re
re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
print re_telephone.match('010-12345').groups()
print re_telephone.match('010-8086').groups()
演算結果:
('010', '12345')
('010', '8086')
Process finished with exit code 0
コンパイル後、正規表現オブジェクトが生成されます。オブジェクト自体に正規表現が含まれているため、対応するメソッドを呼び出すときに正規表現を指定する必要はありません。
パブリックアカウント「 WebDevelopment 」に注目してください。Pythonテストのデモと学習リソースを受け取り、全員が一緒にPythonを学び、世界のメソッドを収集できます。これは、あなたと私が開発するのに便利です。
ご不明な
点がございましたら、QQテクニカルエクスチェンジグループ(668562416)にご参加ください。何か問題や不十分な点がある場合は、読者の
皆様からのコメントや提案をお待ちしております。転載が必要な場合は、どうぞ私に連絡してください。あなたは許可を得て転載することができます、ありがとう
パブリックアカウント「WebDevelopment」へようこそ