SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

正規表現の問題集

正規表現の問題集2(応用編)

肯定先読み・肯定戻り読みの応用

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード SourceCode (1.6 KB)

3. 否定先読みで条件チェック

 次は、否定先読みで条件チェックする正規表現についてです。

検索条件
同じアルファベットの文字列が連続してない行を検索する。
例1 文字列aabcdeは、アルファベットの文字列aが連続しているので不適
例2 文字列abcdcdは、アルファベットの文字列cdが連続しているので不適
例3 文字列abcabcは、アルファベットの文字列abcが連続しているので不適

 対象データと期待する検索結果は、下記となります(黄緑色が検索にヒットした部分です)。

対象データと期待する検索結果
対象データと期待する検索結果

 こういった、同じ文字列の連続を調べる際には、後方参照を使うのがセオリーです。そして、候補となる文字列の組み合わせを全てチェックすることで、答えは下記となります。

答え
^(?!.*([a-z]+)\1).*$

 解説すると、まず行頭で否定先読みを使い.*([a-z]+)\1を満たさないことを条件としています。.*にマッチする文字の数は、0文字以上の文字列ですが、これはバックトラックが発生する量指定子になっています。[a-z]+にマッチする文字の数は、1文字以上の[a-z]ですが、これもバックトラックが発生する量指定子になっています。

 以上により、たとえば検索対象がabcdefで、検索パターンが^(?!.*([a-z]+)\1).*$だとすると、

チェックされる組み合わせ
.*が0文字にマッチ、[a-z]+が1文字にマッチ、キャプチャした\1にマッチ
.*が0文字にマッチ、[a-z]+が2文字にマッチ、キャプチャした\1にマッチ
.*が0文字にマッチ、[a-z]+が3文字にマッチ、キャプチャした\1にマッチ
.*が0文字にマッチ、[a-z]+が4文字にマッチ、キャプチャした\1にマッチ
.*が0文字にマッチ、[a-z]+が5文字にマッチ、キャプチャした\1にマッチ
.*が0文字にマッチ、[a-z]+が6文字にマッチ、キャプチャした\1にマッチ
.*が1文字にマッチ、[a-z]+が1文字にマッチ、キャプチャした\1にマッチ
.*が1文字にマッチ、[a-z]+が2文字にマッチ、キャプチャした\1にマッチ
以下略

 という全ての組み合わせで、同じ文字列が連続するかチェックされます。そして、全ての組み合わせでアンマッチだったら(?!.*([a-z]+)\1)を満たしますので.*$で行全体を検索しています。

 正規表現のイメージは下記となります。

正規表現のイメージ
正規表現のイメージ

次のページ
4. 指定文字列内の、指定文字を検索

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
正規表現の問題集連載記事一覧
この記事の著者

山岸 賢治(ヤマギシ ケンジ)

趣味が競技プログラミングなWebエンジニアで、OracleSQLパズルの運営者。AtCoderの最高レーティングは1204(水色)。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2676 2008/11/07 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング