正規表現(Regular expressions)は文字列内を検索したり置換するための強力な方法です。
JavaScriptでは、正規表現は組み込みの RegExp
クラスのオブジェクトを使用して実装され、文字列と統合されています。
正規表現
正規表現(もしくは “regexp”, または単に “reg”) は パターン とオプションの フラグ で構成されています。
正規表現オブジェクトを生成するための2つの構文があります。
長い構文:
regexp =
new
RegExp
(
"pattern"
,
"flags"
)
;
…そして短い構文です。スラッシュ "/"
を使います:
regexp =
/
pattern
/
;
// フラグなし
regexp =
/
pattern
/
gmi
;
// g, m と i のフラグあり(詳細は後ほど説明します)
スラッシュ /.../
は正規表現を作成していることを JavaScript に伝えます。文字列の引用符と同じ役割を果たします。
どちらの場合も、regexp
は組み込みの RegExp
クラスのインスタンスになります。
これらの構文の主な違いは、スラッシュ /.../
を使用するパターンは式が挿入できないことです(テンプレートリテラル ${...}
のような)。これは完全に静的です。
スラッシュは、コードを書くときに正規表現を知っているときに使われます。そして、これが最も一般的なケースです。 new RegExp
は動的に生成された文字列から “その場” で正規表現を作成する必要がある場合にしばしば使われます。例えば:
let
tag =
prompt
(
"What tag do you want to find?"
,
"h2"
)
;
let
regexp =
new
RegExp
(
`
<
${
tag}
>
`
)
;
// 上のプロンプトで "h2" と入力された場合は、/<h2>/ になります
フラグ
正規表現には検索に影響を与えるフラグを含む場合があります。
JavaScript には 6 つしかありません:
i
- このフラグを指定すると、検索は大文字小文字を区別しません:
A
とa
に違いはありません(下の例をみてください)。 g
- このフラグを指定すると、検索はすべての一致を探します。指定がない場合は – 最初の1つのみを探します(次のチャプターで使い方を見ていきます)。
m
- 複数行モードです(チャプター 記事 "regexp-multiline" が見つかりません で説明します)。
s
- “dotall” モードを有効にします。これにより、ドット
.
が改行文字\n
に一致できるようになります(チャプター 文字クラス で説明しています)。 u
- 完全なユニコードサポートを有効にします。このフラグはサロゲートペアの正しい処理を可能にします。より詳細についてはチャプター Unicode(ユニコード): フラグ "u" とクラス \p{...} を参照してください。
y
- スティッキーモード: テキストの正確な位置で検索します(チャプター スティッキーフラグ(sticky flag) "y", 指定位置での検索 で説明します)。
ここからの配色は次の通りです:
- 正規表現 –
red
- 文字列 (検索する場所) –
blue
- 結果 –
green
検索: str.match
前述のように、正規表現は文字列のメソッドと統合されています。
メソッド str.match(regexp)
は文字列 str
中のすべての regexp
の一致を見つけます。
3つの動作モードがあります:
-
正規表現にフラグ
g
がある場合、すべての一致の配列を返します:let
str=
"We will, we will rock you"
;
alert
(
str.
match
(
/
we
/
gi
)
)
;
// We,we (マッチする2つの部分文字列の配列)
We
とwe
の両方が見つかることに注目してください。フラグi
は正規表現が大文字小文字を区別しないようにします。 -
そのようなフラグがない場合は、配列の形式で最初に一致したものだけを返します。インデック
0
でマッチした内容があり、あといくつか詳細情報のためのプロパティを持っています:let
str=
"We will, we will rock you"
;
let
result=
str.
match
(
/
we
/
i
)
;
// g フラグなし
alert
(
result[
0
]
)
;
// We (最初の一致)
alert
(
result.
length)
;
// 1
// 詳細:
alert
(
result.
index)
;
// 0 (一致した位置)
alert
(
result.
input)
;
// We will, we will rock you (元の文字列)
正規表現の一部が括弧で囲まれている場合は、配列は
0
以外のインデックスを持っている場合があります。これについてはチャプター キャプチャグループ で説明します。 -
そして、最後に、一致するものがなかった場合は
null
が返却されます(フラグg
の有無は関係ありません)。ここに重要な違いがあります。一致するものがない場合、殻の配列を受け取るのではなく
null
を受け取ります。これを忘れるとエラーにつながる可能性があるので注意してください。例えば:let
matches=
"JavaScript"
.
match
(
/
HTML
/
)
;
// = null
if
(
!
matches.
length)
{
// Error: Cannot read property 'length' of null
alert
(
"Error in the line above"
)
;
}
結果を常に配列にしたい場合は次のようにします。:
let
matches=
"JavaScript"
.
match
(
/
HTML
/
)
||
[
]
;
if
(
!
matches.
length)
{
alert
(
"No matches"
)
;
// 問題なく動きます
}
置換: str.replace
メソッド str.replace(regexp, replacement)
は文字列 str
で regexp
を使用して見つけた一致を replacement
に置き換えます(フラグg
があればすべての一致を、そうでなければ最初の1つだけが対象になります)。
例:
// g フラグなし
alert
(
"We will, we will"
.
replace
(
/
we
/
i
,
"I"
)
)
;
// I will, we will
// g フラグあり
alert
(
"We will, we will"
.
replace
(
/
we
/
ig
,
"I"
)
)
;
// I will, I will
2番目の引数は replacement
文字列です。特別な文字の組み合わせを使用して、一致した内容の部分を挿入することもできます。:
記号 | 置換文字列での動作 |
---|---|
$& |
一致したもの全体を挿入します |
$` |
一致の前の部分文字列を挿入します |
$' |
一致した後の部分文字列を挿入します |
$n |
n が1-2桁の数値の場合、n番目の括弧の内容を挿入します。詳細についてはチャプター キャプチャグループ で説明します |
$<name> |
指定された name の括弧の中身を挿入します。詳細についてはチャプター キャプチャグループ で説明します |
$$ |
文字 $ を挿入します |
$&
の例です:
alert
(
"I love HTML"
.
replace
(
/
HTML
/
,
"$& and JavaScript"
)
)
;
// I love HTML and JavaScript
テスト: regexp.test
メソッド regexp.test(str)
は、少なくとも1つの一致を検索し、見つかれば true
を、なければ false
を返します。
let
str =
"I love JavaScript"
;
let
regexp =
/
LOVE
/
i
;
alert
(
regexp.
test
(
str)
)
;
// true
このパートの後半では、より多くの正規表現を学び、より多くの例を見ていき、他のメソッドにも触れます。
メソッドに関する完全な情報は RegExp と文字列のメソッド にあります。
サマリ
- 正規表現はパターンとオプションのフラグで構成されます:
g
,i
,m
,u
,s
,y
. - フラグと特殊記号(後で学びます)がない場合、正規表現による検索は部分文字列検索と同じです。
- メソッド
str.match(regexp)
は一致を探します:g
フラグがあればすべてを、なければ最初の1つだけが対象です。 - メソッド
str.replace(regexp, replacement)
はregexp
を使用して見つけた一致をreplacement
に置換します:g
フラグがあればすべてを、なければ最初の1つだけが対象です。 - メソッド
regexp.test(str)
が少なくとも1つ一致があればtrue
を、なければfalse
を返します。
コメント
<code>
タグを使ってください。複数行の場合は<pre>
を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。