RegExpオブジェクト
JavaScriptには正規表現によって文字列内の検索や置換、パターンマッチングを行えるRegExpオブジェクトがあります。
//で囲むことで正規表現を宣言できますが、これは文字列などではなく、RegExpオブジェクトと呼ばれるものにあたります。
本記事ではRegExpクラスのプロパティやメソッドについてみていきます。
RegExpオブジェクトの作成方法
RegExpオブジェクトは//でパターンを囲むことで作成できます。
const regex = /\d+/ //1個以上の数字
このregexは、TypeScriptではstring型ではなく、RegExp型となります。
また、RegExpコンストラクタを使って、new RegExp("abc","g")やnew RegExp(/abc/g)のように作成することもできます。
RegExpのプロパティ
RegExpオブジェクトには、正規表現の内容に関する情報を持つプロパティが多数存在します。
source
sourceは正規表現の文字列そのものを格納する、read onlyなプロパティです。
const regex = new RegExp(/ab+c/g)
console.log(regex.source) //"ab+c"
console.log(regex.source="bcd") //書き込みは不可
//Cannot set property source of [object Object] which has only a getter
flags
flagsは正規表現のフラグ文字列を格納する、read onlyなプロパティです。
const regex = new RegExp(/ab+c/gi)
console.log(regex.flags) //"gi"
各フラグが設定されているかを表すプロパティ
正規表現ではいくつかのフラグを設定できますが、フラグが設定されているかを表すBoolean型のプロパティが各フラグそれぞれに対して存在しています。全てread only です。
global
gフラグが設定されていればtrue。
正規表現に最初にマッチしたものだけでなく、文字列内での全てのマッチを検索するようになります。
ignoreCase
iフラグが設定されていればtrue。
大文字・小文字の区別をしなくなります。
multiline
mフラグが設定されていればtrue。
文字列が改行されている場合、^と$は文字列の先頭と末尾だけでなく、各行の先頭と末尾にもマッチするようになります。
dotAll
sフラグが設定されていればtrue。
.が改行も含めてマッチするようになります。
unicode
uフラグが設定されていればtrue。
\u{}によるコードポイントの指定や\p{}、\P{}の使用が可能になります。
sticky
yフラグが設定されていればtrue。
lastIndex番目から検索を行うようになります。
lastIndex
gかyフラグが設定されているときに、検索を開始する位置を指定します。
このプロパティはread only ではなく、書き込み可能です。
例えばRegExp.prototype.testをgやyフラグ付きの正規表現で使用すると、デフォルトでは先頭の文字から検索をはじめますが、lastIndexの値を変更することで、検索開始位置を変更することが可能です。
const regex = new RegExp(/a{3}\d+/g) //"a"の3回の繰り返し後に数字が1回以上繰り返されるパターン
regex.test('aaa123bbb')// true
regex.lastIndex = 4
regex.test('aaa123bbb')//false
lastIndexはプロパティであるため、新たにRegExpのオブジェクトが生成されるケースではデフォルト値の0で処理されてしまうため、lastIndexを指定したオブジェクトとメソッドを呼び出すオブジェクトが同一のものかに注意する必要があります。
RegExpのメソッド
test()
test()はパターンにマッチする場合にtrueを返します。
const regex = /\d+/
regex.test('abc') // false
regex.test('ab1') // true
内部的にはexec()を呼び出しており、exec()の結果がnull以外のときにtrueを返し、nullのときにfalseを返しています。
exec()
exec()は文字列を引数にとり、マッチする場合には配列を返し、マッチしない場合にはnullを返します。
返り値となる配列には1つ目の要素にマッチした文字列、2つ目以降の要素にはサブパターン(キャプチャグループのパターン)にマッチした文字列が格納されています。
また、indexやinput、groupsなど、以下の値を格納しているプロパティももちます。
-
indexは最初にマッチした文字位置 -
inputは検索された文字列 -
groupsは名前付きキャプチャグループのグループ名をキーとし、マッチした文字列を値とするオブジェクト
gフラグを指定していないときのmatchメソッドと同じような返り値ですが、execの場合はgフラグがあっても同様の結果を返します。
動的なデータから正規表現を扱うには
//によって正規表現を宣言するときには、テンプレートリテラル${}が使用できないため、動的なデータを含めることができません。
動的なデータを利用したい時には、//ではなくnew RegExp()によってRegExpオブジェクトを作成する必要があります。
文字列を引数に渡す時にはエスケープ処理に注意が必要です。
/\d+/のようにして作成していた正規表現は、RegExpコンストラクタで作成する時には、\が文字列内でエスケープ用の記号として使用されているため、\自体を指定するには\\のように\をエスケープする必要があります。
const regex = new RegExp("\d+")
regex.test('12345') // false
const regex = new RegExp(`\\d+`)
regex.test('12345') // true
new RegExpであればテンプレートリテラルが使用できるため、動的なデータから正規表現を生成可能です。
const randomNumber = Math.floor(Math.random() * 10) //0から9の整数をランダムに生成
const regex = new RegExp(`${randomNumber}{3}`) //生成された整数が3つ連続で続くことを表す正規表現
//実行例
console.log(randomNumber) // 6
console.log(regex.test('666777888999')) //true