REGEXを学ぶ。 初心者向け'ガイド
このガイドでは、正規表現の構文であるregexを学習します。 このガイドでは、正規表現を学習し、Web 開発で必要とされるほとんどのシナリオで正規表現によるソリューションを適用できるようになります。
- form input validation
- web scraping
- search and replace
- filtering for information in massive text files such as logs
正規表現 (regex, 通称) は複雑で新しいユーザーにとっては威圧的に見えますが、これは間違いではありません。 この例を見てください:
/^+@+(?:\.+)*$/
これは文字化けしたテキストのように見えます。 しかし、絶望しないでください。この狂気の背後に方法があるのです。 まず、このガイドで使用する用語を明確にしましょう。
- pattern: 正規表現パターン
- string: パターンにマッチするテスト文字列
- digit: 0-9
- letter: a-z, A-Z
- symbol: 記号: !$%^&*()_+|~-=`{}:”;'<>?,./
- スペース:単一の空白、タブ
- 文字:文字、数字、記号を指す
Basics
このガイドで正規表現をすばやく学ぶには、正規表現パターンを作成して、提供した文字列(テキスト)に対してテストできる Regex101 を参照してください。
サイトを開いたら、このガイドで使用する JavaScript のフレーバーを選択する必要があります。 (Regex 構文はすべての言語でほぼ同じですが、いくつかの細かい違いがあります。)
次に、Regex101 の global
および multi line
フラグを無効にする必要があります。 これらについては、次のセクションで説明します。 とりあえず、最も単純な正規表現を作って見ましょう。 次のように入力します:
- regex input field: cat
- test string: rat bat cat sat fat cats eat tat cat mat CAT
JavaScriptの正規表現は/
で始まり、/
で終わることに注意してください。 もし、あなたがJavaScriptのコードで正規表現を書くとしたら、次のようになります。 /cat/
となり、引用符はつきません。 上記の状態では、正規表現は文字列 “cat” にマッチする。 しかし、上の画像でわかるように、マッチしない「cat」という文字列がいくつか存在する。 次のセクションでは、その理由について説明します。
Global and Case Insensitive Regex Flags
デフォルトでは、正規表現パターンは最初に見つかったマッチのみを返します。 追加のマッチを返したい場合は、g
で示されるグローバル・フラグを有効にする必要があります。 また、正規表現パターンはデフォルトで大文字と小文字を区別します。 この挙動を上書きするには、i
で示される insensitive フラグを有効にします。 更新された正規表現パターンは、現在 /cat/gi
と完全に表現されています。 以下のように、大文字と小文字が異なるものを含め、すべての “cat” 文字列が一致しました。
文字セット
前の例で、完全に大文字小文字を区別した一致を実行する方法を学びました。 bat”、”cat”、”fat “をマッチさせたいとしたらどうでしょう。 これは、.NETで表記される文字セットを使用することで実現できます。 基本的には、マッチさせたい文字を複数指定する。 例えば、at
は次のように複数の文字列にマッチする。
文字セットは数字でも動作する。 文字セットの中にアルファベットを全部入れることもできるが、それは面倒である。 解決策は次のような範囲を使うことです。 at
:
ここにテストされる完全な文字列があります。 rat bat cat sat fat cats eat tat cat dog mat CAT
.
ご覧のように、すべての単語が期待どおりにマッチしています。 無効なマッチを投げ入れるために、dog
という単語を追加しました。 以下は、範囲を使用する他の方法です:
-
部分範囲:
または
.
-
大文字範囲などの選択部分です。
.
-
桁の範囲。
.
-
Symbol range: 例えば、
.
-
Mixed range: 例えば、
はすべての数字、小文字、大文字を含む。
範囲の定義方法をさらに理解するために、文字がどのように並べられるかを見るために完全な ASCII テーブルを見ることが最善です。 この場合、
このようにすると、すべての3文字の単語にマッチします。 しかし、5文字や8文字の単語をマッチさせたい場合はどうするか。 上記の方法は面倒である。 このようなパターンを表現するには、
{}
中括弧の表記を使ったもっと良い方法がある。 繰り返しの文字数を指定するだけでいいのだ。 以下はその例です。-
a{5}
は “aaaaa” にマッチします。 -
n{3}
は “nnn” にマッチします。 -
{4}
は “door”, “room”, “book” など任意の4文字の単語にマッチします。 -
{6,}
は6文字以上の単語にマッチします。 -
{8,11}
は8文字から11文字までの単語にマッチします。 -
{11}
は11桁の数字にマッチします。
メタキャラクタ
メタキャラクタは、よりコンパクトな正規表現パターンを書くことができます。 ひとつひとつ見ていこう。
-
\d
は -
\w
は任意の文字、数字、アンダースコア文字 -
\s
はホワイトスペース文字、つまり、空白文字にマッチングします。 スペースまたはタブ -
\t
タブ文字のみにマッチ
これまで学んだことから、正規表現はこのように書くことができる。
-
\w{5}
は任意の 5 文字の単語または 5 桁の数字 -
\d{11}
は電話番号などの 11 桁の数字
特殊文字
特殊文字はさらに一歩進んだパターン表現の書き方をします:
-
+
.のように、特殊文字はより進んだパターン表現の作成を可能にします。 1つ以上の量詞(先行する文字は存在しなければならず、オプションで重複も可能)。 例えば、c+at
式は “cat”, “ccat”, “ccccccccat” にマッチします。 先行する文字を何度繰り返してもマッチします。 -
?
のようになります。 0個または1個の量記号(直前の文字は省略可能)。 例えば、c?at
という表現は、”cat” または “at” にのみマッチします。 -
*
となります。 0個以上の量記号(先行する文字は任意で、任意に重複することも可能)。 例えば、c*at
という表現は、”at”、”cat”、”cccccat “にマッチします。+
と?
の組み合わせのようなものです。 -
\
: この「エスケープ文字」は、特殊文字を文字通り使いたいときに使用されるものです。 例えば、c\*
は “c*” に正確にマッチし、”cccccc” にはマッチしない。 -
: この “negate” 記法は、ある範囲内でマッチしてはならない文字を示すために使われる。 例えば、
bld
という表現は、2文字目のaからcが否定的であるため、”bald “や “bbld “にはマッチしない。 7704> -
.
: この “do” 表記は、改行以外のあらゆる数字、文字、記号にマッチします。 例えば、.{8}
は文字、数字、記号からなる8文字のパスワードにマッチする。例えば、”password” と “P@ssw0rd” は両方ともマッチする。
これまで学んだことから、コンパクトだが強力な様々な正規表現を作成することができる。 例えば、
-
.+
は1文字または無制限の数の文字にマッチします。 -
+
は、少なくとも1つの文字を含んでいれば、長さに関係なく、すべての小文字の単語にマッチします。
Groups
先ほどの特殊文字はすべて、1文字または1範囲の集合にしか作用しません。 もし、式の一部に効果を適用したいとしたらどうでしょうか。 これは、丸括弧 –
()
を使用してグループを作成することで実現できます。 たとえば、パターンbook(.com)?
は「book」と「book.com」の両方にマッチします。電子メール検証などの現実的なシナリオで使用される、より複雑な例を次に示します。
@\w+\.\w{2,3}(\.\w{2,3})?
-
- test string:
abc.com abc@mail @mail.com @mail.co.ke
代替文字
正規表現では、「パイプ」記号 – |
を使用して代替文字を指定することができます。 これは、先に示した特殊文字とは異なり、パイプ記号の両側にあるすべての文字に影響します。 例えば、パターンsat|sit
は、”sat “と “sit “の両方の文字列にマッチする。
上記のパターンは、()
括弧を使用することでs(a|i)t
と表現できます。
開始と終了のパターン
いくつかの正のマッチは部分マッチの結果であることにお気づきかも知れません。 たとえば、文字列 “boo” にマッチするパターンを書いた場合、文字列 “book” は完全一致しないにもかかわらず、同様に正のマッチを取得します。 これを改善するために、次の表記を使用します。
-
^
: 先頭に配置、この文字は文字列の先頭でパターンにマッチする。 -
$
: 最後に配置、この文字は文字列の最後でパターンにマッチする。
上記の状況を解決するには、boo$
と表記して、パターンを記述すればよいでしょう。 こうすれば、最後の3文字がパターンにマッチするようになる。 しかし、次の画像が示すように、まだ考慮していない問題があります。
文字列 “sboo” はまだ現在のパターンマッチ要件を満たしているため、マッチを取得します。 これを修正するには、パターンを次のように更新します。 ^boo$
. これにより、”boo “という単語が厳密にマッチするようになります。 両方を使用すると、両方のルールが適用されます。 たとえば、^{5}$
は5文字の単語に厳密にマッチします。 7704>
Regex in JavaScript
// Example 1const regex1=/a-z/ig//Example 2const regex2= new RegExp(//, 'ig')
Node.js がマシンにインストールされている場合、ターミナルを開いて node
コマンドを実行すると Node.js シェルインタプリタが起動します。 次に、次のように実行します:
さらに正規表現パターンで自由に遊んでみてください。 終了したら、コマンド .exit
を使用してシェルを終了します。
Real World Example: 電子メールの検証
このガイドを終えるにあたり、正規表現の一般的な使用法である電子メールの検証について見てみましょう。 (たとえば、ユーザーがフォームに入力した電子メール アドレスが有効な電子メール アドレスであることをチェックしたい場合など)
このテーマは思ったより複雑です。 電子メール アドレスの構文は非常に単純です。 {name}@{domain}
. 理論的には、電子メールアドレスは #-@&%.
などの限られた数の記号を含むことができます。 しかし、これらの記号の配置は重要です。 メールサーバーも、記号の使用について異なる規則を持っています。 例えば、+
の記号は無効とするサーバーもあります。
あなたの知識を試すために、以下に示す有効な電子メールアドレスのみにマッチする正規表現パターンを作成してみてください:
# invalid emailabcabc.com# valid email [email protected]@[email protected]@[email protected]# invalid email [email protected]@[email protected]#[email protected]# valid email [email protected]@[email protected][email protected]# invalid domain [email protected]@mail#[email protected]@mail..com# valid domain [email protected]@[email protected]@[email protected]
有効とマークされた電子メールアドレスが特定の組織で無効である場合もあれば、無効とマークされたものが他の組織で実際に許可されている場合もありますので、ご注意ください。 いずれにせよ、所属する組織のニーズに対応するためには、その組織用にカスタム正規表現を作成することを学ぶことが最も重要です。 万が一、行き詰まった場合は、次のような解決策を検討することができます。 7704>
- 可能な解決策 1:
^\w*(\-\w)?(\.\w*)?@\w*(-\w*)?\.\w{2,3}(\.\w{2,3})?$
- 可能な解決策 2:
^((\.,;:\s@"]+(\.\.,;:\s@"]+)*)|(".+"))@((\{1,3}\.{1,3}\.{1,3}\.{1,3}])|((+\.)+{2,}))$
概要
正規表現の基本はご理解いただけましたでしょうか。 この初心者向けクイックガイドですべての正規表現機能を網羅したわけではありませんが、正規表現による解決を必要とするほとんどの問題に取り組むのに十分な情報を得ることができるはずです。 より詳細については、実世界のシナリオで正規表現を実用的に適用するためのベストプラクティスに関するガイドをお読みください。