【JavaScript】正規表現で変数を使う方法|RegExpの使い方とフラグ一覧(実例で解説。初心者向け)

javascript-prograshi(プロぐらし)-kv JavaScript
記事内に広告が含まれていることがあります。
[PR]

JavaScriptの便利な関数match, search, replaceなどのメソッドでは正規表現を使うことができます。指定する正規表現の中で変数を使用したいという場合もあります。

ここでは、正規表現の中で変数を使う方法についてまとめています。


//の中は文字列しか使えない

まず、そもそもですが正規表現あることを示す / / の中では文字列しか使えません

str.match(/文字列のみ/)
str.match(/文字列のみ/フラグ)

必要に応じて//の後ろに「g」や「i」などのフラグ(オプション)を指定します。

メモ

//を使った正規表現の指定を「リテラル記法」といいます。


実例

str = "This is Super Apple and Pen.";

result = str.match(/A(.*?)e/);
console.log(result[0]);

//結果
Apple




変数を使うには? RegExpオブジェクト

使い方

正規表現の指定部分で変数を使いたいときは、RegExpオブジェクトを使用します。

str= "任意の文字列";

let regexp = new RegExp(正規表現, フラグ);
str.match(regexp)

2つ目のフラッグでは、gやiなどのフラグ(オプション)を指定します。

フラグなしでも使用できます。

new RegExp(正規表現)
注意点

RegExpでは、正規表現も文字列として指定します。

メモ

RegExpのことを「コンストラクター」と呼びます。



実例

let str = "This is Super Apple and Abcde, adde.";

let initial = "A";

regexp = new RegExp(initial + "(.*?)e", "g");
result = str.match(regexp);

console.log(result[0]);

//出力
Apple


RegExpの注意点

RegExpを使うときに注意しなければいけないことがあります。それはバックスラッシュを使う場合は2つ使わなければいけないということです。

例えば、正規表現の1つである「*」を文字列として検索したい場合はバックスラッシュ2つを前につけて「\*」とします。通常の「/ /」の中で記述する場合はバックスラッシュは1つだけでいいのとは大きな違いです。

let word1 = "\\*選択日\\* ";
let regexp1 = new RegExp (word1 + "(.*)");
console.log(regexp1);

//出力結果
/\*選択日\* (.*)/


例えば、以下のような場合があるとします。

let lastName = body.match(/\*苗字\*[\s\S\n]*?\*名前/)

↓ RegExpで書き換え

let word2 = "\\*苗字\\* ";
let word3 = "\\*名前\\* ";

let regexp2 = new RegExp (word2 + "[\\s\\S\\n]*?" + word3);

let lastName = body.match(regexp2)[0]

文字列として「*(アスタリスク)」を指定する場合は、「\\*」とし、「\s」は「\\s」といったように書き換える必要があります。

補足

[\s\S\n]は改行も含めて検索を続けることを示す正規表現です。一般的な(.*)では改行がある場合、その手前でパターンマッチが終了します。

(参考)【JavaScript】正規表現で改行も含めて検索、matchする方法|([\s\S]?、[\s\S\n]、(.))とは何か?



応用編1:通常の正規表現を変数を使って置き換える

例えば以下のように、文字列のみで指定した正規表現があるとします。

let body = `
*選択日* 2025/11/3
*苗字* 山田
*名前* 卓也
*ヨミガナ* ヤマダ タクヤ`;


let reservationDate = body.match(/\*選択日(.*)/)[0].replace( "*選択日* ", "" );
let lastName = body.match(/\*苗字\*[\s\S\n]*?\*名前/)[0].replace( "*苗字* ", "" ).replace( "*名前","" );

console.log(reservationDate);
console.log(lastName);

//結果
2025/11/3
山田


これをRegExpオブジェクトと変数を使って以下のように置き換えることができます。


let body = `
*選択日* 2025/11/3
*苗字* 山田
*名前* 卓也
*ヨミガナ* ヤマダ タクヤ`;

let word1 = "\\*選択日\\* ";
let word2 = "\\*苗字\\* ";
let word3 = "\\*名前\\* ";

let regexp1 = new RegExp (word1 + "(.*)");
let regexp2 = new RegExp (word2 + "[\\s\\S\\n]*?" + word3);


let reservationDate = body.match(regexp1)[0].replace( "*選択日* ", "" );
let lastName = body.match(regexp2)[0].replace( "*苗字* ", "" ).replace( "*名前* ","" );

console.log(reservationDate);
console.log(lastName);


//結果
2025/11/3
山田


エスケープを使う場合に、replaceと組み合わせようとするとあまりいい書き方ではなさそうです、、


応用編2: for文との組み合わせ

RegExpを使うと変数が使用できるようになるため、for文と組み合わせて、似たような文字列が繰り返す場合にまとめて取得することができます。

例えば次のような文字列に対してRegExpを使って、それぞれの名前とフリガナをまとめて取得することができます。

*■予約情報*
*予約ID* #35 
*選択日* 2024年4月18日 
*終了日* 2024年4月18日 
*お名前* TEST 卓也 
*フリガナ* テスト タクヤ 
*電話番号* 1234567898765 
*ゲーム参加人数* 30 
*(2)お名前* TEST1 
*フリガナ* テスト1 
*(3)お名前* TEST2 
*フリガナ* テスト2 
*(4)お名前* TEST3 
*フリガナ* テスト4 
*(5)お名前* AAAAAAAAあ 
*フリガナ* BBBB 
*(6)お名前* CCC 
*フリガナ* DDD 
*(7)お名前* EEE 
*フリガナ* FFF 
*(8)お名前* TEST8 
*フリガナ* テスト8 
*(9)お名前* TEST9 
*フリガナ* テスト9 
*(10)お名前* TEST10 
*フリガナ* テスト10 
*(11)お名前* RRR
*フリガナ* テスト11
*人数(6歳未満)* 3
*食物アレルギー(お食事ご提供のため)* ある


例えば、カッコがついている人の「お名前」と「フリガナ」を取得して、スプレッドシートの1つのセルに収めるように1つの変数にまとめていれる処理は以下になります。

////検索対象の文字列////
let body = `*■予約情報*
*予約ID* #35 
*選択日* 2024年4月18日 
*終了日* 2024年4月18日 
*お名前* TEST 卓也 
*フリガナ* テスト タクヤ 
*電話番号* 1234567898765 
*ゲーム参加人数* 30 
*(2)お名前* TEST1 
*フリガナ* テスト1 
*(3)お名前* TEST2 
*フリガナ* テスト2 
*(4)お名前* TEST3 
*フリガナ* テスト4 
*(5)お名前* AAAAAAAAあ 
*フリガナ* BBBB 
*(6)お名前* CCC 
*フリガナ* DDD 
*(7)お名前* EEE 
*フリガナ* FFF 
*(8)お名前* TEST8 
*フリガナ* テスト8 
*(9)お名前* TEST9 
*フリガナ* テスト9 
*(10)お名前* TEST10 
*フリガナ* テスト10 
*(11)お名前* RRR
*フリガナ* テスト11
*人数(6歳未満)* 3
*食物アレルギー(お食事ご提供のため)* ある` 

// console.log(body);
//console.log("---------------------------------------")


////マッチング処理////
let nameAndFurigana = "";
let name = "";
let furigana = "";
let names = "";

for( i = 2; i < 12; i++ ){
    let regexp1 = new RegExp( `\\*(${i})お名前[\\s\\S\\n]*((${i+1}|\\*人数)`);
    nameAndFurigana = body.match(regexp1)[0];
    // console.log(nameAndFurigana);
    
    let regexp2 = new RegExp( `お名前\\*(.*)?`);
    name = nameAndFurigana.match( regexp2 )[0].replace( "お名前* ", "" );
    // console.log("名前:", name);
    
    let regexp3 = new RegExp( `フリガナ\\*(.*)?`);
    furigana = nameAndFurigana.match( regexp3 )[0].replace( "フリガナ* ", "" );
    // console.log("フリガナ:", furigana);
    
    names += "(" + i + ")" + name + " " + furigana + "\n";
}

console.log(names);
Point1

これはお客様に入力してもらったフォームのデータを想定しています。そのため、パターンマッチングをかけるときは、お客様が入力しない文字を検索のためのキーとして設定する必要があります。

例えば、RegExp(\\*(.*)?)のように、文字列としてのアスタリスクをマッチング開始の条件として設定した場合、仮にお客様がアスタリスクを入力すると、意図しない結果が返ってきます。

完全に防げるわけではないのですが、RegExp( お名前\\*(.*)?)とした方が意図しない結果となる確率を下げることができます。


最後のconsole.logの出力結果は以下のようになります。

(2)TEST1  テスト1 
(3)TEST2  テスト2 
(4)TEST3  テスト4 
(5)AAAAAAAAあ  BBBB 
(6)CCC  DDD 
(7)EEE  FFF 
(8)TEST8  テスト8 
(9)TEST9  テスト9 
(10)TEST10  テスト10 
(11)RRR テスト11

だいぶシンプルでいい感じになりました。


Point2

RegExpの条件として(${i+1}|\*人数)のように、「|」を使ってor条件を設定しています。こうすることで、一番最後のお名前とフリガナも取得することができます。

regexp1 = new RegExp( `\\*(${i})お名前[\\s\\S\\n]*((${i+1}|\\*人数)`);

ちなみにですが、match関数は一致するパターンがないとエラーが発生してします



フラグ一覧

参考までにフラグの一覧を記載しておきます。

フラグ説明対応するプロパティ
d一致した部分文字列の位置を生成します。hasIndices
gグローバル検索を行います。global
i大文字・小文字を区別しない検索です。ignoreCase
m複数行の検索です。multiline
s. が改行文字に一致するようにします。dotAll
u“unicode” です。パターンを一連の Unicode コードポイントとして扱います。unicode
y対象文字列の現在の位置から始まる部分に一致するものを探す「先頭固定」 (sticky) 検索を行います。 sticky を参照してください。sticky

(参考)Mdn 正規表現


タイトルとURLをコピーしました