正規表現

正規表現での?(クエスチョン,ハテナ)の用法4つ | 先読みや最短一致も

正規表現でのハテナマークの用法を解説

用法1.「?」単体で前の文字を「0回or1回」

「?」の最も一般的な使い方が「直前の文字を0回または1回」を表すものです。ここでいう文字は特殊文字や省略記法、文字クラス、グループなどを含め「?」の使い方は多岐にわたります。

// 直前の文字があってもなくてもOK
ABC?
// ヒットするもの
AB
ABC

// 「.」や「\d」といった特殊文字および省略記法も対象
ポリゴン.?
// ヒットするもの
ポリゴン
ポリゴン2
ポリゴンZ

// [ ]や( )でくくった場合はそれ全体を0回または1回
[+-]?123456
// ヒットするもの
123456
+123456
-123456

用法2.「?:」で「() グループ化」のキャプチャ対象外

「?:」は「()」でグループしたものをキャプチャの対象外とする書き方です。たとえば「(?:hoge)」とかくことで「hoge」をキャプチャした際に置き換えの対象外として明示できます。

// 対象の文字列
みつけた ポケモン 123!
つかまえた ポケモン 45!

// キャプチャしたい文字列
123 45

// 実際に試してみた
(みつけた|つかまえた) ポケモン (\d{1,3})! // みつけた, 123, つかまえた, 35
(?:みつけた|つかまえた) ポケモン (\d{1,3})! // 123, 45
シャワーズ

仮にキャプチャをなにかに使うことがなくても、可読性や保守性の観点からキャプチャに使っていないことを明示するために「?:」をつけるケースはあります!

用法3. 「?=」「?!」で先読み「?<=」「?<!」で後読み

「?=」「?!」「?<=」「?<!」はそれぞれ肯定先読みや否定先読みの用法で用います。2文字以上をマッチさせるケースが多いので「(?=hoge)」のように「()」のなかで使用されるケースが多いです。それぞれの使い方は次のとおり。

  • 「?=」は肯定先読み
  • 「?!」は否定先読み
  • 「?<=」は肯定後読み
  • 「?<!」は否定後読み

用法4. 「*?」「+?」「??」「{n,m}?」で最短一致

「*」「+」「?」「{n,m}」の量指定子と呼ばれる繰り返しを表す記号と組み合わせて使うことで最短一致をできるようになります。それぞれの量指定子はもともと次のような意味をもっていて

これらに「?」をつけると最短一致をするようになります。

  • 「*?」は前の文字を0回以上繰り返し(最短一致)
  • 「+?」は前の文字を1回以上繰り返し(最短一致)
  • 「??」は前の文字を0回または1回(最短一致)
  • 「{n,m}?」は前の文字をn回〜m回繰り返し(最短一致)

最短一致の例は下のとおりです。

// 対象の文字列
リザードンサイドンヤドンウツドン

// キャプチャしたい文字列
リザードン, サイドン, ヤドン, ウツドン

// 実際に試してみた
(.*ドン) // リザードンサイドンヤドンウツドン
(.*?ドン) // リザードン, サイドン, ヤドン, ウツドン

単に「(.*ドン)」としてしまうとリザー”ドン”でとどまらず最後のウツ”ドン”まで拾ってしまう最長一致となってしまいます。これを防ぐには量指定子の「*」に「?」をつけて「(.*?ドン)」とすることで最短一致するようになります。