Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ 先読み、後読み、非貪欲マッチング | 高度な正規表現と応用
Python正規表現

先読み、後読み、非貪欲マッチング

メニューを表示するにはスワイプしてください

先読み(lookahead)後読み(lookbehind)、および非貪欲量指定子(non-greedy quantifiers)などの高度な正規表現機能を理解することで、Pythonにおいて非常に精密なパターンマッチングが可能になります。先読み後読みは**ゼロ幅アサーション(zero-width assertions)**の一種であり、現在位置の前後に特定のパターンが存在するかどうかを判定しますが、そのパターン自体はマッチ結果に含まれません。非貪欲量指定子は、パターンが消費するテキストの量を制御し、必要最小限の部分だけをマッチさせることができます。

  • 先読み(?=...) の形式で記述し、現在位置の直後に特定のパターンが続くかどうかを判定します。
  • 後読み(?<=...) の形式で記述し、現在位置の直前に特定のパターンがあるかどうかを判定します。
  • *?+? などの非貪欲量指定子は、デフォルトの貪欲な動作を変更します。
  • 通常、*+ などの量指定子はできるだけ多くのテキストをマッチしますが、? を付けることで非貪欲となり、できるだけ少ないテキストだけをマッチします。

先読みの例:\w+(?=\d) は、単語の直後に数字が続く場合のみその単語をマッチしますが、数字自体はマッチ結果に含まれません。後読みも同様の機能ですが、逆方向に動作します。

1234567891011121314
import re # Lookahead: Match words followed by a digit text = "apple1 banana2 cherry pie" pattern_lookahead = r"\w+(?=\d)" matches_lookahead = re.findall(pattern_lookahead, text) print("Lookahead matches:", matches_lookahead) # Non-greedy matching: Extract text between tags html = "<b>Bold</b> and <b>Strong</b>" pattern_nongreedy = r"<b>(.*?)</b>" matches_nongreedy = re.findall(pattern_nongreedy, html) print("Non-greedy matches:", matches_nongreedy)

先読みと非貪欲量指定子がパターンマッチングに与える影響

例の先読みパターン \w+(?=\d) は、単語文字の並び(\w+)の直後に数字(\d)が続く場合のみマッチします。マッチ結果には数字は含まれません。これは、先読みが判定対象の文字を消費しないためです。次に続く部分をマッチ結果に含めず、特定の条件を満たす単語だけを抽出したい場合に有用です。

非貪欲量指定子 *? を使った <b>(.*?)</b> では、<b></b> タグの間のテキストをマッチします。貪欲な量指定子 .* だと最初の <b> から最後の </b> まで全てをマッチしてしまいますが、*? を使うことで、各タグペアごとに最小限のテキストだけを個別に抽出できます。これにより過剰なマッチングを防ぎ、最小限の部分文字列だけを取得できます。

先読みや非貪欲量指定子を使うことで、正規表現によるテキスト抽出の制御力が大きく向上します。

  • 先読みは、特定のパターンが後に続くことを判定しつつ、その部分をマッチ結果に含めません。
  • 非貪欲量指定子は、必要以上に多くのテキストをマッチすることを防ぎます。
question mark

非貪欲量指定子 *? は何をしますか?

正しい答えを選んでください

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 3.  1

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

先読み、後読み、非貪欲マッチング

先読み(lookahead)後読み(lookbehind)、および非貪欲量指定子(non-greedy quantifiers)などの高度な正規表現機能を理解することで、Pythonにおいて非常に精密なパターンマッチングが可能になります。先読み後読みは**ゼロ幅アサーション(zero-width assertions)**の一種であり、現在位置の前後に特定のパターンが存在するかどうかを判定しますが、そのパターン自体はマッチ結果に含まれません。非貪欲量指定子は、パターンが消費するテキストの量を制御し、必要最小限の部分だけをマッチさせることができます。

  • 先読み(?=...) の形式で記述し、現在位置の直後に特定のパターンが続くかどうかを判定します。
  • 後読み(?<=...) の形式で記述し、現在位置の直前に特定のパターンがあるかどうかを判定します。
  • *?+? などの非貪欲量指定子は、デフォルトの貪欲な動作を変更します。
  • 通常、*+ などの量指定子はできるだけ多くのテキストをマッチしますが、? を付けることで非貪欲となり、できるだけ少ないテキストだけをマッチします。

先読みの例:\w+(?=\d) は、単語の直後に数字が続く場合のみその単語をマッチしますが、数字自体はマッチ結果に含まれません。後読みも同様の機能ですが、逆方向に動作します。

1234567891011121314
import re # Lookahead: Match words followed by a digit text = "apple1 banana2 cherry pie" pattern_lookahead = r"\w+(?=\d)" matches_lookahead = re.findall(pattern_lookahead, text) print("Lookahead matches:", matches_lookahead) # Non-greedy matching: Extract text between tags html = "<b>Bold</b> and <b>Strong</b>" pattern_nongreedy = r"<b>(.*?)</b>" matches_nongreedy = re.findall(pattern_nongreedy, html) print("Non-greedy matches:", matches_nongreedy)

先読みと非貪欲量指定子がパターンマッチングに与える影響

例の先読みパターン \w+(?=\d) は、単語文字の並び(\w+)の直後に数字(\d)が続く場合のみマッチします。マッチ結果には数字は含まれません。これは、先読みが判定対象の文字を消費しないためです。次に続く部分をマッチ結果に含めず、特定の条件を満たす単語だけを抽出したい場合に有用です。

非貪欲量指定子 *? を使った <b>(.*?)</b> では、<b></b> タグの間のテキストをマッチします。貪欲な量指定子 .* だと最初の <b> から最後の </b> まで全てをマッチしてしまいますが、*? を使うことで、各タグペアごとに最小限のテキストだけを個別に抽出できます。これにより過剰なマッチングを防ぎ、最小限の部分文字列だけを取得できます。

先読みや非貪欲量指定子を使うことで、正規表現によるテキスト抽出の制御力が大きく向上します。

  • 先読みは、特定のパターンが後に続くことを判定しつつ、その部分をマッチ結果に含めません。
  • 非貪欲量指定子は、必要以上に多くのテキストをマッチすることを防ぎます。
すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 3.  1
some-alt