MENU

JavaScript正規表現

【JavaScript】 正規表現まとめメモ

更新日:2020/04/10

 

正規表現の作成方法と使い方

 

正規表現は、RegExpオブジェクト(正規表現オブジェクト)を使用する。

 

 

RegExpオブジェクトの作成方法は2種類

 

正規表現のパターンが固定の場合、正規表現リテラルを使用できる。
正規表現リテラルは、正規表現パターンを『/』で囲ったものである。

 

正規表現リテラルを使用

const rg = /正規表現パターン/オプション;

 

例:
const rg = /(a\d)(bc)/g;

 

パターンを動的に設定したい場合は、RegExpオブジェクトのコンストラクターを使用する。

 

正規表現(RegExp)オブジェクトのコンストラクターを使用

const rg = new RegExp( 正規表現パターン , オプション );

 

例:
const rg = new RegExp( "(a\\d)(bc)" , "g");

 

重要 new RegExp()でのエスケープ

 

正規表現のメソッド

 

RegExpオブジェクトはそれ自体が持っていてるメソッドを使用するケースと、Stringオブジェクトのメソッドに引数として与えるケースがある。

 

 

test()メソッド

 

test()はRegExpオブジェクトのメソッド。

 

一致するかどうかをテストし、結果としてtrueまたはfalseを返す。

 

const testString = "abcdef";
const rg = /cde/; // 正規表現の作成
const result = rg.test( testString );   //  /cde/.test( )でもOK
console.log( result ); // true

 

 

search()メソッド

 

search()は、Stringオブジェクトのメソッド。

 

最初に一致した位置(0~)を返す。
一致しない場合は、-1を返す。

 

const testString = "abcdef";
const rg = /cde/; // 正規表現の作成
const result = testString.search( rg );
console.log( result ); // 2

 

match()メソッド/exec()メソッド

 

match()とexec()は、一致した文字列を取得するメソッドです。

 

match()は、Stringオブジェクト(文字列オブジェクト)が持つメソッドです。
一方exec()は、RegExpオブジェクト(正規表現オブジェクト)が持つメソッドです。

 

const text = "123abc#$%abc";
const rg = /abc/;
const result = rg.exec( text );  // または text.match( rg );

 

結果:

 

result : Array{
        0 : "abc"
        1 : "bc"
        index : 3
        input : "123abc#$%abc"
        length : 2
    }

 

詳しくはこちらの記事を参照してください。
【JavaScript】 正規表現match()とexec()の違い

 

replace()メソッド

 

replace()は、Stringオブジェクトのメソッド。

 

文字列の置換をおこなうメソッドだが、正規表現を使用しないと最初の一回しか置換してくれない。
全て変換したいときは、正規表現が必須となる。

 

例:雨を飴に置換

const text = "雨食べたい。甘い雨を食べたい。";
const rg = /雨/g;
const result = text.replace( rg , "飴" );

 

結果:

 

result : "飴食べたい。甘い飴を食べたい。"

 

詳しくはこちらの記事を参照してください。
【JavaScript】 replace()の使い方 単純な置換と正規表現での置換

 

split()メソッド

 

replace()は、Stringオブジェクトのメソッド。

 

split()は、文字列を任意の文字列で分割して、配列にセットするメソッド。
任意の文字には正規表現

 

例:カンマまたは | で分割

const text = "abc,def|ghi";
const result = text.split( /[,|]/ );

 

結果:

 

result : Array{
        0 : "abc"
        1 : "def"
        2 : "ghi"
    }

 

詳しくはこちらの記事を参照してください。
【JavaScript】 split()で正規表現を使って文字列分割してみる

正規表現パターン

 

基本は一文字マッチの組み合わせ

 

正規表現はまず一文字のマッチから組み立てる。

 

カンマの付いた4桁の数値とマッチ: /\d,\d\d\d/
大文字のアルファベットと3桁の数値にマッチ: /[A-Z]\d\d\d/

 

パターン 意味
[ ] [ ]内に羅列した一文字とマッチ "abc123".match( /[b2]/g )
"b"と"2"にマッチ
[ - ] -で文字の範囲を指定。
[A-Z]、[a-z]、[0-9]、[A-Za-z]のように使用する
[ ]内で-を検索したいときは\-
"abc123".match( /[0-9]/g )
"1"、"2"、"3"にマッチ
"abc123".match( /[a0-9]/g )
"a"、"1"、"2"、"3"にマッチ
[^ ] [ ]内に羅列した文字または範囲以外とマッチ "abc123".match( /[^ab12]/g )
"c"と"3"にマッチ
"abc123".match( /[^a-z]/g )
"1"、"2"と"3"にマッチ
. 改行以外にマッチ "abc".match( /.../ )
"abc"にマッチ
\d 数値にマッチ。
[0-9]と同じ意味。
"abc123".match( /\d\d\d/ )
"123"にマッチ
\D 数値以外にマッチ。[^0-9]と同じ意味。 "abc123".match( /\D\D\D/ )
"abc"にマッチ
\n,\r,\r\n 改行と一致(OSにより異なる) "ab\r\ncd\r\nef".replace( /\r\n/g , "\n" )
改行コードを\n\rから\nに変換
\s 改行・スペース・タブ・空白と一致 /\d\s\d/.exec( "1,2 34" )
"2 3"にマッチ
\S \s以外とマッチ /\d\S\d/.exec( "1,2 34" )
"1,"にマッチ
\w 数値・アルファベット・アンダースコア(_)にマッチ
[A-Za-z0-9_]と同じ
"明日はAM8時に出発".match( /\w\w\w/ )
"AM8"にマッチ
\W \w以外とマッチ "明日はAM8時に出発".match( /\W\W\W/ )
"明日は"と"時に出"にマッチ

 

 

指定回数の繰り返し 【 {}  ? 】

 

{ }または?を使用すると、同じ文字(パターン)を指定した回数だけ繰り返したときマッチする。

 

パターン 意味
{ n } 直前のパターンを
n回繰り返すとマッチ
"abc123".match( /\d{3}/g )
"123"にマッチ
{ n , m } 直前のパターンを
n回以上m回以下繰り返すとマッチ
"12_345_6789".match( /\d{3,5}/g )
"345""6789"にマッチ
{ n , } 直前のパターンを
n回以上繰り返すとマッチ
"12_345_6789".match( /\d{4,}/g )
"6789"にマッチ
? 0回または1回繰り返すとマッチ
{ 0 , 1 }と同じ
"1A2_34".match( /\d[A-Z]?\d/g )
"1A2"、"34"にマッチ

 

 

回数不明の繰り返し 【 * + 】

 

繰り返す回数が不明の場合、*または+を指定する。

 

パターン 意味
* 直前のパターンを
0回以上繰り返すとマッチ
"a123_a".match( /a\d*/g )
"a123"と"a"にマッチ
+ 直前のパターンを
1回以上繰り返すとマッチ
"a123_a".match( /a\d+/g )
"a123"にマッチ

 

結構重要:最短最長マッチ 【 ? 】

 

通常*または+を使用した繰り返しは、一番長い範囲でマッチする。

 

例:
"12ABCD#78EF#".match( /.+#/g )
期待する結果は"12ABCD#""78EF#"だが、実際には"12ABCD#78EF#"がマッチする。

 

この場合、*または+の後に?を使用することで最短マッチに変更できる。
(0回または1回繰り返しの?とは区別するべき)

 

"12ABCD#78EF#".match( /.+?#/g )

 

先頭・末尾マッチ  【 ^ $ 】

 

^または$は、文字列の先頭または行末にマッチする。

 

パターン 意味
^ 先頭を意味する "123_456".match( /^\d\d\d/ )
"123"にマッチ
$ 先頭を意味する "123_456".match( /\d\d\d$/ )
"456"にマッチ

 

グループ  【 ( )  】

 

パターンの一部を( )で囲うと、囲まれた範囲はグループとなります。
グループは複数指定できます。

 

キャプチャグループ

 

グループは、マッチした文字列とは別に各々記憶(キャプチャ)されます。
そのためキャプチャグループとも呼ばれます。

 

例:

 

/(ABC)DE/.exec( "ABCDEF" )

 

結果:

 

Array[0] : "ABCDE"  // マッチした文字列
Array[1] : "ABC"         // キャプチャされた文字列

exec()の結果については次の記事を見てください。
【JavaScript】 正規表現match()とexec()の違い

 

グループ単位で繰り返し

 

グループごとに繰り返しパターンを適用できます。

 

例:

/(ABC)+DE/.exec( "ABCABCDEF" )

 

結果:

 

Array[0] : "ABCABCDE"  // マッチした文字列
Array[1] : "ABC"         // キャプチャされた文字列

 

非キャプチャグループ

 

(?: )のように記述されたグループは、キャプチャされません。

 

例:

/((?:ABC)+)DE/.exec( "ABCABCDEF" )

 

結果:

 

Array[0] : "ABCABCDE"  // マッチした文字列
Array[1] : "ABCABC"         // キャプチャされた文字列

 

通常、入れ子のグループでもそれぞれキャプチャされます。
この例では内側のグループをキャプチャの対象から外しています。

 

複数の文字列(条件)のうち一つに一致  【 | 】

 

| を使用すると、複数の文字列のうち一つにマッチさせることができます。

 

例:

/A..|D..|G../g.exec( "ABC_DEF_GHI" )

 

結果:
"ABC"、"DEF"、"GHI"にマッチ

 

先読み・後読みマッチ  【 (?= ) (?| ) (?<= ) (?<! ) 】

 

文字列の前、または後にどんな文字があるかをマッチ条件に加えます。
さらに、その前後の文字はマッチした文字として取り扱いません。

 

パターン 意味
x(?=y) 先読み。
xの後ろにyがある場合xがマッチする。
yはマッチ結果に含まれないが、
キャプチャとして取得される。
"ABCDEFG".match(/.(?=DE)/g )
"C"にマッチ
x(?!y) 否定先読み。
xの後ろにyがない場合xがマッチする。
yはマッチ結果に含まれないが、
キャプチャとして取得される。
"ABCDEFG".match(/.(?!DE)/g )
"A", "B", "D", "E", "F", "G"にマッチ
(?<=y)x 後読み。
xの前にyがある場合xがマッチする。
yはマッチ結果に含まれないが、
キャプチャとして取得される。
一部のブラウザは非実装
"ABCDEFG".match(/(?<=DE)./g )
"F"にマッチ
(?<=y)x 否定後読み。
xの前にyがない場合xがマッチする。
yはマッチ結果に含まれないが、
キャプチャとして取得される。
一部のブラウザは非実装
"ABCDEFG".match(/(?<=DE)./g )
"A", "B", "C", "D", "E", "G"にマッチ

メタ文字のエスケープ  【 \ 】

 

メタ文字は、正規表現で特別な意味をもつ文字です。

 

正規表現のメタ文字:
\ ^ . $ * ? | ( ) [ ] { }
正規表現リテラルの場合は / を含む

 

通常のエスケープ

 

これらの文字を普通の文字としてマッチされるときは、文字の前に\を記述します。

 

\\ \^ \. \$ \* \? \| \( \) \[ \] \{ \}
正規表現リテラルの場合 \/ 

 

/.\../g.exec( "a.bc" )

 

結果: "a.b"にマッチ

 

[ ]内のエスケープ

 

[ ]内では、一部を除き普通の文字として扱われます。
そのため\でエスケープする必要がありません。

 

ただし次のメタ文字はエスケープが必要です。
- ]

 

"12/ab[]cd".match( /[/ab[\]]/g )

 

結果:"/", "a", "b", "[", "]"にマッチ

 

重要 new RegExp()でのエスケープ

 

エスケープはRegExpオブジェクトのコンストラクタを使用する場合、エスケープ文字の前に\を記述する必要があります。

 

[ ]内のエスケープの例を、new RegExp()で書き換えてみます。

 

例:new RegExp()でエスケープ

const rg = new RegExp("[/ab[\]]","g");
"12/ab[]cd".match( rg );

 

結果は"[]"にマッチします。

 

\は文字列中でもエスケープを意味するため、生成された文字列はエスケープした結果となります。

 

どのような文字列が作成されたか見てみます。

 

console.log( "[/ab[\]]" )

 

結果:"[/ab[]]"
\が消えています。

 

new RegExp()には、エスケープ文字も渡さないと、うまく処理してくれません。

 

文字列中で\を文字として扱うためには、\\と記述します。

 

console.log( "[/ab[\\]]" )

 

結果:"[/ab[\]]"
\が表示されました。

 

これをnew RegExp()に渡せば、期待通りの処理をしてくれます。

 

例:new RegExp()でエスケープの改良

const rg = new RegExp("[/ab[\\]]","g");
"12/ab[]cd".match( rg );

 

結果:"/", "a", "b", "[", "]"にマッチ

 

期待通りの結果となりました。

正規表現のオプションフラグ

 

パターン 意味
g グローバルサーチ。
繰り返しマッチングをおこなう。
"ABCDEFG".match(/[A-Z]{3}/g )
"ABC", "DEF"にマッチ
i 大文字小文字を区別しない "ABCDEFG".match(/dEf/i )
"DEF"にマッチ
s 正規表現パラメーターの『.』が改行と一致
一部のブラウザはエラーになる
"ABCD\nEFG".match(/C.*/s )
"CD↵EFG"にマッチ
m 行別(複数行)検索
正規表現パラメーターの『^』『$』が行ごとに適用される。
"ABCD\nEFG".match(/..$/gm )
"CD", "FG"にマッチ

まとめ

正規表現は難しいイメージがありますが、理屈的にはそれほど難しくないようです。

 

パターンを記憶できるかどうかは別問題ですが…

記事の内容について

 

こんにちはけーちゃんです。
説明するのって難しいですね。


「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。

そんなときは、ご意見もらえたら嬉しいです。

ご意見はこちら。
https://affi-sapo-sv.com/info.php

【お願い】

お願い

■このページのURL


■このページのタイトル


■リンクタグ