コンテンツにスキップ

正規表現—応用編

より精密な「捜査技術」を身につける

7. 正規表現—基礎編で、私たちは正規表現という「魔法の呪文」の基礎を学びました。.(任意の文字)、*+(繰り返し)、()(グループ化)、[](文字クラス)など、探偵が容疑者の特徴を記述するための基本的な記号を手に入れました。

しかし、言葉の探偵として解決すべき謎は、もっともっと複雑なときがあります。この章では、正規表現の「奥義」とも言える高度なテクニックを学びます。

この章で学ぶこと

  • 先読み・後読みで、特定のパターンの前後を条件に指定して検索する。
  • エスケープを利用して、メタ文字を普通の文字として扱う。

基礎編のおさらい

まず、基礎編で学んだ内容を整理しておきましょう。

メタ文字 意味 マッチする例
. 任意の1文字 満面.笑 満面の笑/満面ノ笑
* 0回以上 言語学.* 言語学/言語学者
+ 1回以上 [ぁ-ん]+ あ/あいうえお
{n} ちょうどn回 あ{3} あああ
{n,} n回以上 あ{2,} ああ/あああ...
{n,m} n〜m回 あ{2,4} ああ/あああ/ああああ
| または 日本|韓国 日本/韓国
() グループ化・キャプチャー (ぴか)\1 ぴかぴか
[] 文字クラス [ぁ-ん] ひらがな1文字
? 直前のパターンの0か1回の出現 ですね。? ですね。/ですね
^ 文字列の先頭
$ 文字列の末尾
\s 半角・全角スペースやタブなどの空白
\S \s 以外
\w ワード文字([A-Za-z0-9_]と同じ)
\W \w 以外
\d 半角の数字([0-9]と同じ)
\D \d 以外([^0-9]と同じ)
\t タブ
\r\n 改行
\n VS Codeでの改行

以下は、英数字にマッチさせる文字クラスです。

文字クラス 意味
 [a-z] 小文字のaからzまで
 [A-Z] 大文字のAからZまで
 [a-zA-Z] すべてのアルファベット
 [0-9] 数字(0から9まで)
 [a-zA-Z0-9] アルファベットと数字

以下は、日本語にマッチさせるための文字クラスです。

文字種 文字クラス 意味
漢字 [一-龠] 日常的に使われるほぼすべての漢字
ひらがな [ぁ-ん] すべてのひらがな
カタカナ [ァ-ヴー] すべてのカタカナ

先読みと後読み

探偵が現場を観察するとき、証拠を動かさずに「見るだけ」の場合があります。正規表現の先読み(lookahead)は、これに似ています。先読みは、「この後に○○が続くのか、続かないのか」という条件をチェックしますが、その部分自体はマッチの結果に含まれません。

肯定先読み

肯定先読み(positive lookahead)は、「【パターン】の後に【条件】が続く」という条件を表します。

パターン(?=条件)

それ、触らないで!

「言語学」「心理学」「社会学」などの「学」の前にある部分だけを抽出したいと考えてみましょう。つまり、「言語」「心理」「社会」だけをマッチさせたいということです。

文字列
哲学
言語
言語学
心理学
日本語学
学校
正規表現
[一-龠]{2,}(?=学)

上記の正規表現にマッチするのは「言語」「心理」「社会」のみです。「学」自体はマッチに含まれていないことを確認してください。この正規表現が意味するのを砕けて言うと、以下のようになります。

  • [一-龠]{2,} → 漢字2文字以上にマッチ
  • (?=学) → その後に「学」が続くことを確認(ただし「学」自体はマッチに含めない)

否定先読み

否定先読み(negative lookahead)は、肯定先読みとは反対に、「【パターン】の後に【条件】が続かない」という条件を表します。

パターン(?!条件)

目指すは日本

「日本」という単語を検索したいけれど、「日本語」や「日本人」といった複合語の一部として使われている場合は除外したい(国としての日本だけを抽出したい)場面を考えてみましょう。

文字列
日本に行く
日本語を学ぶ
日本人の友達
日本文化
正規表現
日本(?!語|人)

上記の正規表現では、「語」または「人」が後ろに続く「日本」にはマッチしません。

  • 日本 → まず「日本」という文字を探す
  • (?!語|人) → その直後に「語」または「人」が続かないことを確認

肯定後読み

後読み(lookbehind)は、先読みの逆です。肯定後読み(positive lookbehind)は、「【条件】の後に【パターン】がある」という条件を表します。

(?<=条件)パターン

「お」や「ご」に続く漢字の抽出

接頭辞「お」や「ご」が動詞の前に現れることがあります。このパターンに該当する漢字を網羅的に抽出する場面を考えてみましょう。

文字列
お待ちください。
お子様ランチをお届けします。
ご連絡いたします。
待ってください。
お荷物をお預かりしています。
正規表現
(?<=お|ご)[一-龠]+(?=[ぁ-ん])

肯定先読みの部分でひらがなを指定しているので、「お子様ランチ」にはマッチしません。

否定後読み

否定後読み(negative lookbehind)は、「【条件】の後に【パターン】がない」という条件を表します。

(?<!条件)パターン

過去の「た」を探す

五段活用の動詞は「買った」「待った」のように促音が入ります。ここでは、「見た」や「食べた」のような、上一段活用や下一段活用の動詞に「た」が使われている例を抽出してみましょう。

文字列
五段活用:買った・待った・乗った・飲んだ・遊んだ
上一段活用:見た・起きた・信じた
下一段活用:食べた・寝た・開けた
カ行変格活用:来た
サ行変格活用:した
正規表現
(?!来)[一-龠]([ぁ-ん])?(?<!っ)た

  • (?<!っ) → 直前に促音「っ」がないことを確認
  • → 「見た」「食べた」の「た」にマッチ

先読みと後読みをまとめてみると、以下のようになります。

記法 名前 意味
(?=...) 肯定先読み …の先にパターンがある
(?!...) 否定先読み …の先にパターンがない
(?<=...) 肯定後読み …の後にパターンがある
(?<!...) 否定後読み …の後にパターンがない

エスケープ

文字列を扱うときには、正規表現として使われているメタ文字. * + ? | ( ) [ ] { } ^ $などを、普通の文字として扱いたい場合があるかもしれません。そのようなときには、\を使ってエスケープします。

ピリオドを検索したい

以下の文字列にある「3.14」を検索するつもりで3.14と入力すると、うまくいきません。

文字列
価格は3.14ドルです。
3a14
3b14
正規表現
3.14

正規表現で.は「任意の1文字」を意味するので、「3a14」「3b14」などにもマッチしてしまいます。このような場面では\が役に立ちます。

正規表現
3\.14

\(バックスラッシュ)でエスケープすると、.を文字そのものとして扱えます。

メタ文字をエスケープする必要が出てくる場面として、たとえば、以下のような例が考えられます。

メタ文字 エスケープ
. \. 3\.14 → 3.14
* \* 2\*3 → 2*3
+ \+ 1\+1 → 1+1
? \? 本当\? → 本当?
| \| A\|B → A|B
( ) \( \) \(注\) → (注)
[ ] \[ \] \[1\] → [1]
{ } \{ \} \{2\}
^ \^ 2\^3 → 2^3
$ \$ \$100 → $100
\ \\ C:\\ → C:\

括弧で囲まれた数字を抽出

文字列
詳細は、参考文献(1)を参照。なお、参考文献(2)と(3)には、この主張と異なる意見が述べられている。
正規表現
\([0-9]+\)

待ちに待った課題

以下のページを確認して、ピボットテーブルの作り方を練習してみましょう。

一度練習が終わったら、みなさんが調べてみたい表現を取り上げて「中納言」から検索し、ピボットテーブルを作ってみましょう。