Python RegExのマスタリング:パターンマッチングへの深い探求

Python RegExのマスタリング:深いパターンマッチング探求

Python RegExの解読:Pythonのreモジュールを使ってパターンマッチングの芸術を解読する

Canvaで作成した画像

Python RegExまたは正規表現とは何ですか?

正規表現(正規化表現)は、テキストの処理において強力なツールとして使用されます。基本的には、検索のためのパターンを確立する一連の文字から構成されます。このパターンは、パターンのマッチング、テキストの置換、文字列の分割など、さまざまな文字列操作に使用することができます。

正規表現の歴史

画像の出典:http://serge.mehl.free.fr/chrono/Kleene.html

数学者のStephen Cole Kleeneは、1950年代に正規表現を導入し、正規集合または正規言語を記述するための表記法として使用しました。

今日では、正規表現はプログラマーやデータサイエンティスト、ITプロフェッショナルにとって必須のスキルとなっています。

Python RegExまたは正規表現の重要性と使用例

Pythonを使用してこれらの正規表現を使用する方法に入る前に、さまざまなアプリケーションの範囲を見て、自分自身をモチベーション付けましょう。

  • データの検証: 正規表現は、さまざまなタイプのデータを検証するのに非常に役立ちます。(電子メールアドレス、電話番号)
  • Webスクレイピング: Webページをスクレイピングする際には、正規表現を使用してHTMLを解析し、必要な情報を取り出すことができます。
  • 検索と置換: 正規表現は、特定のパターンに一致する文字列を特定し、代替の文字列に置換するのに適しています。この機能は、テキストエディタやデータベース、コーディングなどで特に有用です。
  • シンタックスハイライト: いくつかのテキストエディタは、シンタックスハイライトに正規表現を使用しています。
  • 自然言語処理(NLP): NLPでは、トークン化、ステミングなどのタスクに正規表現を使用することができます。
  • ログ分析: ログファイルの処理では、正規表現を使用して特定のログエントリを抽出したり、時間の経過に伴うパターンを分析するのに効果的です。

さあ、もう十分にモチベーションが湧いていますね!

それでは、正規表現についてのreモジュールから始めましょう。

Pythonのreモジュールの始め方

素晴らしいですね、Pythonのreモジュールの基礎から始めましょう。次のセクションでは、より高度なトピックをカバーします。

reモジュールの紹介

Pythonは、reモジュールを介して正規表現をサポートしています。

このモジュールはPythonの標準ライブラリであり、外部でインストールする必要はありません。Pythonのインストールに含まれています。

reモジュールには、さまざまな関数やクラスが含まれており、正規表現を扱うために使用されます。一部の関数はテキストのマッチングに使用され、他の関数はテキストの分割やテキストの置換に使用されます。

正規表現を扱うために特化したさまざまな関数やクラスが含まれています。これらのうち、一部の関数はテキストのマッチングに、残りの関数はテキストの分割やテキストの置換に使用されます。

reモジュールのインポート

先程も述べましたが、インストールされているので心配する必要はありません。

そのため、Pythonで正規表現を使用するには、まずreライブラリをインポートする必要があります。次のようにインポートステートメントを使用してこれを行うことができます。

import re

ライブラリがインポートされたら、reモジュールが提供する関数やクラスなどの機能を使用できます。

簡単な例から始めましょう。

「Python」という単語のすべての出現箇所を見つけたいとしましょう。

reモジュールのfindall()関数を使用することができます。

以下にコードを示します。

import re # サンプルテキスト text = "Pythonは素晴らしいプログラミング言語です。Pythonはさまざまな分野で広く使用されています。" # 'Python'のすべての出現箇所を見つける matches = re.findall("Python", text) # マッチ結果を出力する print(matches)

以下は出力結果です。

reモジュールには、より複雑なパターンを作成するために使用できるさまざまな関数があります。

しかし最初に、reモジュールの一般的な関数を見てみましょう。

reモジュールの一般的な関数

Pythonの正規表現の基礎を説明する前に、まず一般的な関数を見て、残りの概念をより理解しましょう。reモジュールには、さまざまな関数が含まれています。これらを使用することで、さまざまな操作を行うことができます。

以下のパートでは、それらの一部を見つけていきます。

Image created by the author on Canva

a. re.match() 関数

re.match()関数は、正規表現が特定の文字列で始まるかどうかをキャッチします。

マッチがある場合、関数はマッチオブジェクトを返します。マッチがない場合はNoneを返します。

次に、re.match()関数を使用します。ここでは、文字列textが単語「Python」で始まるかどうかをチェックし、結果をコンソールに出力します。

以下にコードを示します。

import repattern = "Python"text = "Pythonは素晴らしいです。"# テキストが 'Python' で始まるかどうかをチェックするmatch = re.match(pattern, text)# 結果を出力するif match:    print("一致が見つかりました:", match.group())else:    print("一致が見つかりませんでした")

以下は出力結果です。

結果は、パターン「Python」がテキストの先頭と一致していることを示しています。

b. re.search() 関数

re.search()関数は、re.match()とは異なり、文字列全体をスキャンし、一致が見つかった場合はマッチオブジェクトを返します。

以下のコードでは、re.search()関数を使用して、文字列textの中の単語「素晴らしい」を検索します。単語が見つかった場合は表示し、それ以外の場合は「一致が見つかりませんでした」と表示します。

以下にコードを示します。

pattern = "素晴らしい"text = "Pythonは素晴らしいです。"# テキスト内でパターンを検索するmatch = re.search(pattern, text)# 結果を出力するif match:    print("一致が見つかりました:", match.group())else:    print("一致が見つかりませんでした")

以下は出力結果です。

出力結果は、指定されたテキストから「素晴らしい」が見つかったことを示しています。

c. re.findall() 関数

re.findall()関数は、文字列内のパターンの重複しないすべての一致を収集し、これらの一致を文字列のリストとして返します。

以下の例では、re.findall()関数を使用して文字列内のすべての「a」を検索します。マッチした箇所はリストとして返され、それをコンソールに出力します。

以下にコードを示します。

pattern = "a"text = "これはテキストの例です。"# テキスト内の 'a' のすべての出現箇所を見つけるmatches = re.findall(pattern, text)# 一致結果を出力するprint(matches)

以下は出力結果です。

出力は、テキスト内で見つかった「a」という文字のすべての重複しない出現を表しています。

d. re.finditer() 関数

re.finditer() 関数は re.findall() に似ていますが、イテレータを返し、マッチオブジェクトを生成します。

以下のコードでは、re.finditer() 関数を使用して文字列テキスト内の「a」という文字のすべての出現を見つけます。イテレータのマッチオブジェクトを返し、それぞれのマッチのインデックスと値を出力します。

以下はコードです。

pattern = "a"text = "これは例文です。"# テキスト内の 'a' のすべての出現を見つけるmatches = re.finditer(pattern, text)# マッチを出力するfor match in matches:    print(f"マッチが見つかったインデックス {match.start()}: {match.group()}")

以下は出力です。

出力は、テキスト内のパターン「a」のインデックスを示しています。

e. re.sub() 関数

re.sub() 関数は、文字列の置換を行うために使用されます。

次に、re.sub() 関数を使用して「Python」を「Java」に置換します。

変更された文字列を出力します。

以下はコードです。

pattern = "Python"replacement = "Java"text = "Pythonが好きです。Pythonは素晴らしいです。"# 'Python' を 'Java' に置換して新しいテキストを取得しますnew_text = re.sub(pattern, replacement, text)# 新しいテキストを出力しますprint(new_text)  # 出力: "Javaが好きです。Javaは素晴らしいです。"

以下は出力です。

出力は、テキスト内の「Python」を「Java」に正常に置換できることを示しています。

次のセクションでは、正規表現で使用できるさまざまなテキストパターンに一致するための基本的なパターンについて説明します。

Python 正規表現の基本的なパターン

まず、基本的なパターンから始めましょう。

正規表現は、リテラル文字、メタ文字、数量子の組み合わせによって構築されます。したがって、これらの基本要素を把握することは、効果的な正規表現を作成するために重要です。

まずはリテラル文字から始めましょう。

a. リテラル文字

リテラル文字は、正規表現でのパターンマッチングの最も簡単な形式です。

リテラル文字はそのまま自分自身に一致し、特別な意味を持ちません。

例えば、正規表現 python は文字列 python と完全に一致します。

import re pattern = "python"text = "Pythonでプログラミングが好きです!" # 'Python' のすべての出現を見つけるmatches = re.findall(pattern, text) # マッチを出力するprint(matches)

以下は出力です。

出力は、re.findall() 関数がパターン「python」のすべてのインスタンスを見つけたことを示しています。

b. メタ文字

「.」、「^」、「$」のようなメタ文字は、文字列を操作するのに非常に重要です。詳細を見ていきましょう。

i. ドット (.)

ドット . はジョーカーカードのようなものです。改行以外の任意の1文字に一致します。

以下のコードでは、正規表現パターン「p.t」を使用します。

以下はコードです。

import re pattern = "p.t"text = "pat, pet, p5t, ただし pt は除く。" # 'Python' のすべての出現を見つけるmatches = re.findall(pattern, text) # マッチを出力するprint(matches)

以下は出力です。

出力は、コードが「p」で始まり「t」で終わる3つの文字のインスタンスをすべて見つけたことを示しています。

ii. キャレット (^)

キャレット ^ は、文字列が特定の文字で始まるかどうかをチェックするために使用されます。

例を見てみましょう。

以下のコードは、テキストがHelloで始まるかどうかをチェックします(一致が見つかりました:「一致」)または見つからないかどうか(一致が見つかりません)

以下はコードです。

import repattern = "^Hello"text = "Hello, world!"# re.match()を使用する理由は、文字列の先頭でのみ一致をチェックするためですmatch = re.match(pattern, text)# 一致を出力するif match:    print("一致が見つかりました:", match.group())else:    print("一致が見つかりません")

以下は出力です。

出力には、コードがテキストの先頭にあるhelloパターンをキャッチしていることが示されています。

iii. ドル記号 ($)

ドル記号 $ は、文字列が特定の文字で終わるかどうかをチェックするために使用されます。

以下のコードは、テキストがworld$で終わるかどうかをチェックします(そうであれば「一致が見つかりました:」一致)またはそうでないかどうか(そうであれば「一致が見つかりません」)

以下はコードです。

import repattern = "world$"text = "Hello, world"# re.search()を使用して、文字列全体を検索しますmatch = re.search(pattern, text)# 一致を出力するif match:    print("一致が見つかりました:", match.group())  # 出力:一致が見つかりました: worldelse:    print("一致が見つかりません")

以下は出力です。

出力には、re.search()関数が「world」で終わるテキストを見つけたことが示されています。

c. 量指定子

量指定子は、一致させようとしているパターンに文字(または文字)が何回出現するかを定義するために使用されます。

このセクションでは、アスタリスク(*)の例を見て、プラス記号(+)で続け、疑問符(?)で終わり、中括弧({})で終わります。

アスタリスクから始めましょう。

i. アスタリスク (*)

正規表現のアスタリスク(*)は、前の文字が0回以上繰り返されることを示します。

コードを見てみましょう。以下のコードでは、まずパターン(「py」)を定義し、それからfindall()関数を使用します。

以下はコードです。

import repattern = "py*"text = "p py pyy pyyy pyyyy"matches = re.findall(pattern, text)print(matches)

以下は出力です。

出力には、アスタリスクが「y」が0回以上出現することを許可しているため、すべてが表示されています。

ii. プラス (+)

プラス + は、前の文字の1回以上の繰り返しに一致します。

ここでもpyパターンを使用してfindall()関数を使用しますが、今回はプラス(+)を使用します。

以下はコードです。

import repattern = "py+"text = "p py pyy pyyy pyyyy"matches = re.findall(pattern, text)print(matches)  # 出力:['py', 'pyy', 'pyyy', 'pyyy']

以下は出力です。

出力を見ると、プラスは「p」の後に1回以上の「y」文字を必要とします。

iii. 疑問符(?)

疑問符 ? は、前の文字の0回または1回の繰り返しに一致します。前の文字をオプションにします。

以下はコードです。

import repattern = "py?"text = "p py pyy pyyy pyyyy"matches = re.findall(pattern, text)print(matches)  # 出力:['p', 'py', 'p', 'p', 'p']

以下は出力です。

出力では、「p」と「py」のみが一致していることがわかります。なぜなら、疑問符は「y」が1回または0回現れることを許可しているからです。

iv. 中括弧({})

中括弧{}を使用すると、特定の繰り返し回数に一致させることができます。

import repattern = "py{2,3}"text = "py、pyy、pyyy、pyyyy"matches = re.findall(pattern, text)print(matches)  # 出力: ['pyy', 'pyyy', 'pyy']

以下は出力です。

この例では、パターンは「pyy」と「pyyy」に一致しますが、「py」や「pyyyy」には一致しません。なぜなら、「p」の後に正確に2つまたは3つの「y」文字があることを指定しているからです。

Python正規表現の特殊文字

特殊文字は、より複雑なパターンを構築するために使用できます。

Canvaで作成した画像

a. 文字クラス

まず文字クラスを見てみましょう。

以下の例では、3つの文字クラスを見てみます。

まずは「\d」と「\D」から始めましょう。

i. \d、\D

「\d」は数字(0から9)を見つけるために使用され、それとは反対に「\D」は数字でない要素を見つけるために使用されます。

以下のコードでは、「\d」がテキスト文字列をスキャンし、テキストから数字を取得しています。

import repattern = "\d"text = "私の電話番号は123-456-7890です。"# テキスト内のすべての数字を見つけるmatches = re.findall(pattern, text)# 一致するものを出力するprint(matches)

以下は出力です。

出力では、テキスト内のすべての数字(0-9)が見つかったことが示されています。

ii. \s、\S

「\s」は空白文字を見つけるために使用され、その反対に「\S」は空白以外のものを見つけるために使用されます。

以下のコードでは、正規表現「\s」が与えられたテキスト内のすべてのスペースとタブを識別します。

以下はコードです。

import repattern = "\s"text = "これはスペースと\tタブを含むテキストです。"# テキスト内のすべての空白文字を見つけるmatches = re.findall(pattern, text)# 一致するものを出力するprint(matches)  # 出力: [' ', ' ', ' ', ' ', ' ', ' ', '\t']

以下は出力です。

出力から、すべての空白文字を識別できることがわかります。

iii. \w、\W

「\w」は単語(文字、数字、アンダースコア)を見つけるために使用され、「\W」はその反対です。

以下のコードでは、「\w」がテキストからすべての文字と数字を取得します。

以下はコードです。

import repattern = "\w"text = "これは単語と数字123を含む例です!"# テキスト内のすべての単語文字を見つけるmatches = re.findall(pattern, text)# 一致するものを出力するprint(matches)

以下は出力です。

b. 事前定義された文字クラス

事前定義された文字クラスは、一般的なクラスのショートカットを提供します。たとえば、”\d”は数字を表す事前定義された文字クラスです。

この場合、”\d”パターンは与えられたテキストからすべての数字を抽出します。

import repattern = "\d"text = "The year is 2023."# テキスト内のすべての数字を検索するmatches = re.findall(pattern, text)# マッチした結果を出力するprint(matches)

ここに出力結果があります。

出力結果には、コードがテキスト内の事前定義された文字クラス”\d”(すべての数字を表す)のすべてのインスタンスを見つけたことが示されています。

c. カスタム文字クラス

カスタム文字クラスを使用すると、角括弧 [] を使用して独自の文字セットを定義できます。

以下の例では、カスタム文字クラス “[aeiou]” を使用してテキスト内のすべての母音を見つけます。

以下にコードを示します。

import repattern = "[aeiou]"text = "This is an example text."# テキスト内のすべての母音を検索するmatches = re.findall(pattern, text)# マッチした結果を出力するprint(matches)

ここに出力結果があります。

出力結果には、定義した通りのテキスト内のすべての母音のインスタンスが表示されます。

また、”-“を使用して文字の範囲を定義することもできます。

以下にコードを示します。

pattern = "[A-Z]"text = "This is an Example Text With Uppercase Letters."# テキスト内のすべての大文字を検索するmatches = re.findall(pattern, text)# マッチした結果を出力するprint(matches)

ここに出力結果があります。

ここでは、出力結果はテキスト内の大文字のみです。

Pythonの正規表現のコンパイル

スクリプトで同じ正規表現を複数回使用する場合、まずパターンオブジェクトにコンパイルすることで時間を節約することができます。これにより、正規表現は各使用ごとに再解析する必要がなくなります。

a. compile()メソッド

re.compile()メソッドは、正規表現パターンをパターンオブジェクトにコンパイルするために使用できます。

このパターンオブジェクトを使用すると、そのメソッド(テキストのマッチング、検索などの操作)を呼び出すことができます。

以下にコードを示します。

import re# 正規表現パターンをコンパイルするpattern = re.compile(r'\d+')  # 1つ以上の数字にマッチ# パターンオブジェクトを使用してマッチを検索するテキスト = "There are 3 apples and 4 oranges."matches = pattern.findall(text)# マッチした結果を出力するprint(matches)

ここに出力結果があります。

出力結果には数字が表示されます。

b. 正規表現のコンパイルの利点

正規表現を使用することの利点は次のとおりです。

  • パフォーマンス:再利用される場合は、特に高速です。
  • 再利用性:コンパイルされたパターンオブジェクトは、コードの異なる部分で複数回再利用することができます。
  • 読みやすさ:パターンオブジェクトを使用すると、複雑な正規表現を使用している場合でもコードがよりクリーンになります。

以下に、正規表現をコンパイルした単純な例を示します。

import re# 正規表現パターンをコンパイルするpattern = re.compile(r'\d+')  # 1つ以上の数字にマッチ# 異なるテキストでマッチを検索するテキスト1 = "There are 3 apples."text2 = "I have 15 dollars and 30 cents."# テキスト1でマッチを検索するmatches1 = pattern.findall(text1)# テキスト2でマッチを検索するmatches2 = pattern.findall(text2)# マッチした結果を出力するprint(matches1)

ここに出力があります。

では、2番目のテキストを確認しましょう。

ここにコードがあります。

print(matches2)

ここに出力があります。

上記の例は、再利用性、パフォーマンス、可読性の重要性を理解するための比較的単純な例です。特に、パターンを繰り返し使用する場合に重要です。

実践例:電話番号の抽出

このセクションでは、テキストから電話番号を抽出するためのPythonスクリプトを書いて一緒に発見したものをテストしましょう。

これは、特にデータクリーニングプロセスで正規表現がよく使用される一般的な用途です。

a. 正規表現パターンの定義

電話番号は、異なる国や地域によって異なる形式で表されることがありますので、この例ではXXX-XXX-XXXXという形式を考えてみましょう。ここで、Xは数字です。

次のコードは、上記の形式に一致し、このパターンに準拠するパターンを定義しています。

コードをご覧ください。

import re# 電話番号のための正規表現パターンを定義するphone_number_pattern = re.compile(r'\d{3}-\d{3}-\d{4}')

b. findall()メソッドの使用

この例では、findall()メソッドを使用して、パターンに一致する電話番号を抽出します。

次のコードは、正規表現パターンを使用して

import re# 電話番号のための正規表現パターンを定義するphone_number_pattern = re.compile(r'\d{3}-\d{3}-\d{4}')# 電話番号が含まれるテキストtext = """John Doe: 123-456-7890Jane Doe: 234-567-8901Office: 555-555-5555"""# テキスト内のすべての電話番号を見つけるphone_numbers = phone_number_pattern.findall(text)

c. 結果の表示

最後に、抽出した電話番号をコンソールに出力しましょう。

コードをご覧ください。

# 電話番号を出力するprint("Phone numbers found:")for phone_number in phone_numbers:    print(phone_number)

ここに出力があります。

d. 完全な例のコード

以下に、上記の手順を組み合わせた完全なPythonスクリプトがあります。

import re# 電話番号のための正規表現パターンを定義するphone_number_pattern = re.compile(r'\d{3}-\d{3}-\d{4}')# 電話番号が含まれるテキストtext = """John Doe: 123-456-7890Jane Doe: 234-567-8901Office: 555-555-5555"""# テキスト内のすべての電話番号を見つけるphone_numbers = phone_number_pattern.findall(text)# 電話番号を出力するprint("Phone numbers found:")for phone_number in phone_numbers:    print(phone_number)

ここに出力があります。

ベストプラクティス

正規表現を使用する際には、次のベストプラクティスに注意してください:

  • シンプルに保つ:シンプルさが重要です。正規表現は瞬時に複雑になる可能性があるため、一般的にはよりシンプルなパターンを使用することが推奨されます。
  • パターンにコメントを追加する:プロジェクトのために正規表現を開発する際には、コード内にコメントを含めることを忘れないでください。正規表現は複雑になる可能性がありますが、一度コメントを追加すると、コードが再利用可能になります。
  • 徹底的にテストする:正規表現は複雑な性質を持つため、予期しない結果が発生する場合があります。そのため、繰り返しテストすることで、意図した通りに動作することを確認してください。
  • 生の文字列を使用する:Pythonでテキストを操作する際には、バックスラッシュ(\)や改行(\n)など、通常の文字とは異なる意味を持つ特殊文字を使用することがあります。この混乱を避けるために、Pythonでは「生の文字列」と呼ばれるものを使用することができます。文字列の最初の引用符の直前に文字「r」を置くことで、文字列が「生の文字列」となるようにします。これにより、Pythonはその文字列内のバックスラッシュを通常の文字として扱い、特殊な文字として扱わないようにします。

結論

このガイドでは、Python RegExまたは正規表現の領域を探求しました。一般的な関数と基礎から始め、より高度な概念と実践的な例を進めました。ただし、実際のプロジェクトを行うことを忘れずに、それはあなたのキャリアの一環としてこの理解を深めるための例となります。そうすることで、Pythonの正規表現に取り組む際にGoogle検索をする手間を省きながら、知識を深めることができます。

この包括的なPythonの高度な概念ガイドをチェックして、そのような概念の概要を把握してください。

この記事を読むことで、Python RegExについても有益な情報を得ることができたことを願っています。

読んでいただき、ありがとうございました!

元の記事はhttps://www.stratascratch.comで公開されています。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more