正規表現の先読みと後読みはややこしいですね。しかも忘れた頃に出てきますし。
ここでははじめての正規表現とベストプラクティス#4 先読みと後読みを極めるを元に
一つ一つ見ていきます
#実行環境
正規表現はRubularを使うとさっと試せます
#先読み
例えば検索したい文字の後の文字に何か条件をつけたい場合
正規表現1(?=正規表現2)
とすることで正規表現1
でヒットした文字列より後に正規表現2
がヒットした場合に
正規表現1
をヒットできます
例
文字列の中、東京、新横浜のうち駅と付いている文字列を検索したい場合
(東京|新横浜)(?=駅)
とすると
検索文字列 | 検索結果(太文字が検索結果) |
---|---|
東京駅 | 東京駅 |
新横浜駅 | 新横浜駅 |
新横浜の中 | 新横浜の中 |
海老名SA | 海老名SA |
##否定先読み
同じく、条件で検索したい文字列の後に、正規表現を検索したい場合
正規表現1(?!正規表現2)
とすると今度は
正規表現1
でヒットした文字列より後に正規表現2
がヒットしない場合に正規表現1
をヒットさせことができます
例
文字列中に東京、新横浜で●●駅と付いていない検索を行いたい場合
(東京|新横浜)(?!駅)
とすると
検索文字列 | 検索結果(太文字が検索結果) |
---|---|
東京駅 | 東京駅 |
新横浜駅 | 新横浜駅 |
新横浜の中 | 新横浜の中 |
海老名SA | 海老名SA |
#後読み
今度は検索したい文字よりも前に何か正規表現での検索がある場合、
(?<=正規表現1)正規表現2
とすることで
正規表現1
でヒットした文字列より後に正規表現2
がヒットした場合に
正規表現2
をヒットさせることができます
例
文字列のうち、新横浜と付いている駅
を検索
(?<=新横浜)駅
検索文字列 | 検索結果(太文字が検索結果) |
---|---|
東京駅 | 東京駅 |
新横浜駅 | 新横浜駅 |
新横浜の中 | 新横浜の中 |
海老名SA | 海老名SA |
#否定後読み
(?<!正規表現1)正規表現2
とすると、正規表現2
にマッチする文字列かつ,直前に正規表現1
にマッチする文字列が存在しない場合に正規表現2
をヒットさせます
例
文字列のうち、駅
を検索したい。ただし新横浜と付いていない駅
(?<!新横浜)駅
検索文字列 | 検索結果(太文字が検索結果) | 備考 |
---|---|---|
東京駅 | 東京駅 | |
新横浜駅 | 新横浜駅 | |
新横浜の中 | 新横浜の中 | |
海老名SA | 海老名SA | |
駅 | 駅 | (注) |
(注)このように否定の場合、新横浜以外は全て(たとえ何も記載がなくても)ヒットしてしまいます。そのため、検索結果を限定したい場合(?<!新横浜|\s)駅
のように空白文字や改行も対象外とする必要があります
今回はここまで
(2019/06/28修正)
後読みで長さ不定の表現が使えない
後読みで長さの異なる文字列を検索する事は不可と記載しましたが、可能でした。お詫び申しまします。