正規表現(REGular EXPression)

 
Web Tips.
Booskanium's
Booskanium's Web Tips.

JavaScriptの正規表現の落書きあんちょこ、未だにあんちょこが無いと正規表現が使えない。^^;

構文

MDN正規表現
MDN RegExp
MDN正規表現を試す
RegExp クラス

正規表現のコンストラクタの書き方

書き方その1:正規表現リテラルで記述
スクリプト読み込み時にその正規表現がコンパイルされる。

let str = "なっから ちゅんラヂ";
let exp = /ちゅん/ig;

//プロパティにアクセスする必要がない場合
console.log(/ちゅん/ig.test(str));	//true

//プロパティにアクセスする必要がある場合
console.log(exp.test(str));		//true

let exec1 = exp.exec(str);		//"index:5 last index:8 input:なっから ちゅんラヂ はちゅんラジオ"
console.log(`index:${exec1.index} last index:${exp.lastIndex} input:${exec1.input}`);	
let exec2 = exp.exec(str);		//"index:12 last index:15 input:なっから ちゅんラヂ はちゅんラジオ"
console.log(`index:${exec2.index} last index:${exp.lastIndex} input:${exec2.input}`);	
console.log(exp.exec(str));		//null

console.log(exp.test(str));		//true 注意:execの前に記述すると上記のexec2がnull

let match1 = str.match(exp);
console.log(`${match1} Length:${match1.length}`);	//"ちゅん,ちゅん Length:2"

書き方その2:RegExpコンストラクタで記述
スクリプト実行時に正規表現がコンパイルされる。

let str = "なっから ちゅんラヂ はちゅんラジオ";
let exp = new RegExp("ちゅん", "ig");
console.log(exp.test(str));			//true
※プロパティにアクセスする必要がない場合
console.log(new RegExp("ちゅん", "ig").test(str));		//true

メソッドのオブジェクトの使い分け

正規表現オブジェクトのメソッドと、Stringオブジェクトのメソッドの中での正規表現利用がある。
この違いを認識しておかないとコーディングでこんがらかる。

  • 正規表現のメソッド
    RegExpオブジェクトのメソッド
  • compile
    正規表現オブジェクト.compile(パターン,オプション)
    正規表現の事前コンパイルだが、現在は正規表現リテラルで記述するので使うことはない。
  • test
    正規表現オブジェクト.test(対象文字列)

    引数に指定した文字列がパターンにマッチするかをtrue/falseで返る。

    Usage

    const str = 'table football';
    const regex = new RegExp('foo*');
    const globalRegex = new RegExp('foo*', 'g');
    console.log(regex.test(str));		//true
    console.log(globalRegex.lastIndex);	//0
    console.log(globalRegex.test(str));	//true
    console.log(globalRegex.lastIndex);	//9

    マッチ判定の論理値が返るだけ

    もしマッチした位置が知りたい場合はexecまたはmachAllまたはsearchメソッドを利用する。またはString.prototype.search() メソッドを利用する。

  • exec
    正規表現オブジェクト.exec(対象文字列)

    引数に指定した文字列にパターンにマッチした結果を含む配列を返る。マッチしない場合は配列ではなくnullが返る。
    gフラグを指定した場合はnullが返るまで繰り返す。

    配列の値は

    [0]:マッチした文字列全体
    [1]~[n]:パターン文字列の()で囲まれた文字列

    戻り値の配列には以下のプロパティが戻る。

    ・length: マッチした数
    ・index: マッチした相対位置
    ・input: 対象文字列
    ・indices: MDNのRegExp.prototype.exec()を参照

    正規表現オブジェクトの変更されるプロパティ

    ・lastIndex: ヒット文字列の次の文字相対位置
    ・dotAll: MDNのRegExp.prototype.exec()を参照
    ・hasIndices: MDNのRegExp.prototype.exec()を参照
    ・ignoreCase: MDNのRegExp.prototype.exec()を参照
    ・global: MDNのRegExp.prototype.exec()を参照
    ・multiline: MDNのRegExp.prototype.exec()を参照
    ・source: MDNのRegExp.prototype.exec()を参照
    ・sticky: MDNのRegExp.prototype.exec()を参照
    ・unicode: MDNのRegExp.prototype.exec()を参照

    Usage

    const regexp = RegExp('foo[a-z]*','g');
    const str = 'table football, foosball';
    let matchArray;
    while ((matchArray = regexp.exec(str)) !== null) {
      console.log(`Found ${matchArray[0]} start=${matchArray.index} end=${regexp.lastIndex}.`);
    }

  • Stringのメソッド
    Stringオブジェクトのメソッドで正規表現を利用
  • match
    対象文字列.match(正規表現オブジェクト)

    対象文字列のmatchメソッドに正規表現を記述する。マッチした結果を含む配列を返る。
    パターンのマッチ判定は配列のlengthプロパティで判定する。
    なお、正規表現オブジェクトのプロパティは返らない。

    Usage

    const str = 'The quick brown fox jumps over the lazy dog. It barked.';
    const regex = /[A-Z]/g;
    const matchArray = str.match(regex);
    console.log(matchArray);	//["T", "I"]

  • matchAll
    対象文字列.matchAll(正規表現オブジェクト)

    対象文字列のmatchメソッドに正規表現を記述する。マッチした結果を含む配列を返る。
    execより優れているのは、for...of、 配列スプレッド、 Array.from() 構造と効率よく組み合わせることができる。

    Usage

    const regexp = RegExp('foo[a-z]*','g');
    const str = 'table football, foosball';
    const matches = str.matchAll(regexp);
    for (const match of matches) {
      console.log(`Found ${match[0]} start=${match.index} end=${match.index + match[0].length}.`);
    }

  • search
    対象文字列.search(正規表現オブジェクト)

    引数に指定した文字列がパターンにマッチした文字相対位置が返る。マッチしに場合は-1が返る 。

    Usage

    const paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?';
    const regex = /[^\w\s]/g;
    console.log(paragraph.search(regex));		//43
    console.log(paragraph[paragraph.search(regex)]);	//"."

  • replace
    対象文字列.replace(正規表現オブジェクト)

    replace() メソッドは、pattern に一致する文字列の一部またはすべてを replacement で置き換えた新しい文字列が返る。 pattern には文字列または正規表現 (RegExp) を指定することができ、 replacement には文字列または一致するごとに呼び出される関数を指定することができます。 pattern が文字列の場合、最初に一致した箇所のみを置き換える。
    詳しくはMDNのString.prototype.replace()を参照。

    Usage

    const str = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';
    console.log(str.replace('dog', 'monkey'));
    // expected output: "The quick brown fox jumps over the lazy monkey. If the dog reacted, was it really lazy?"
    const regex = /Dog/i;
    console.log(str.replace(regex, 'ferret'));
    // expected output: "The quick brown fox jumps over the lazy ferret. If the dog reacted, was it really lazy?"

  • replaceAll
    対象文字列.replaceAll(正規オブジェクト)

    pattern にマッチしたすべての文字列を replacement で置き換えた新しい文字列を返します。pattern は文字列または RegExp を指定することができ、replacement は文字列または各マッチに対して呼び出される関数を指定することができます。
    詳しくはMDNのString.prototype.replaceAll()を参照。

    Usage

    const str = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';
    console.log(str.replaceAll('dog', 'monkey'));
    		//The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?
    const regex = /Dog/ig;
    console.log(str.replaceAll(regex, 'ferret'));
    		//The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?

  • split
    対象文字列.split(正規表現オブジェクト)

    文字列を分割した結果が格納された配列オブジェクトを返す。
    詳しくはMDNのString.prototype.split()を参照。

    Usage

    const str = 'One Two Three.';
    
    const splits = str.split(/ /g);
    console.log(words);		// Array ["One", "Two", "Three"]
    console.log(`words.length:${words.length}`);	// words.length: 3

  • プロパティ

pattern

Assertions

Assertions(アサーション)、因みに「言明」という日本語訳より横文字のままで良いケース。

MDN 言明


						

Stringメソッドに正規表現を書く

Stringメソッドの引数に正規表現が書ける。 MDNのStringオブジェクト


						

事例

数値を文字列に編集

数値と小数点以下桁数を指定して電卓書式の文字列に変換

_n2string(num, numDecimal) {
    return Number(num).toFixed(numDecimal).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
}

文字列を数値に変換

数値に関わらない文字は無視

_s2num(s) {
    let sign = 1;
   	if (s.match(/\-/)) {
      	sign = -1;
    }
    let num = _k2a_num(s).replace(/[^.0-9]/g, '');
    if (num == '') {
	    return 0;
    } else {
     	return parseFloat(num) * sign;
    }
}

全角数字文字を半角数字文字に変換

_k2a_num(s) {
   	return s.replace(/[+-0-9]/g, (s)=> {
	    return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
   	});
}