[javascript] 正規表現でgオプションを付けた時のデメリット

2019年8月31日

Javascript テクノロジー プログラミング

プログラムをコーディングしていると、意図しない結果になって原因がわからず、ひたすら時間だけが過ぎていく状態がたまにあります。 多くの場合、言語仕様を取り違えていたり、複雑な組み合わせで間違いに気が付きにくい場合などですが、簡単な処理であってもこういう事態に陥ることがあり、所謂「ハマる」という状態です。 今回はjavascriptにおける正規表現からの戻り値で、想定の結果にならずに困ったという話になります。

やりたかったこととその結果

正規表現を使い場面は結構多く、特定の文字列から、指定の形式にマッチしているかどうか、とある単語が含まれているかを検索する場合や、入れ替えする時などに非常に便利に使えます。 例えば、以下のような文字列から、 "{*}"の*部分を一覧で抜き出したい時・・・ var str = "{a}-{b}-{c}-{d}"; var str = "{a}-{b}-{c}-{d}"; var reg = RegExp(/\{(.+?)\}/,"g"); var res = reg.exec(str); console.log(res2); > ["{a}", "a"] execの場合は、gオプションが効かず、最初にマッチしたものをそのパターン毎に配列で返してくれます。 var str = "{a}-{b}-{c}-{d}"; var reg = RegExp(/\{(.+?)\}/,"g"); var res = str.match(reg); console.log(res1); > ["{a}", "{b}", "{c}", "{d}"] 次にmatchで行うとgオプションは効きますが、"(.+?)"箇所の抜き出しが返されません。 PHPでやると、多次元配列でマッチしたパターン分と、ヒットした個数がそのまま取得できるんですが、javascriptはどうやらそれとは結果が違って、1次元配列でしか返らない仕様のようです・・・ リファレンスページには、こうした例の表記はされていないようなので、javascriptの仕様として理解しておかないと行けないようですね。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match

PHPと同じ様な結果を返すための強引な方法

mapプロパティで強引に検索結果を文字列コントロールするやり方が最もシンプルかもしれません。 var str = "{a}-{b}-{c}-{d}"; var reg = RegExp(/\{(.+?)\}/,"g"); var res = str.match(reg).map(function(value){return value.replace("{","").replace("}","");}); console.log(res); > ["a", "b", "c", "d"] また、PHPのような多次元配列で返すには以下のように書くパターンもあります。 var str = "{a}-{b}-{c}-{d}"; var reg = RegExp(/\{(.+?)\}/,"g"); var res = str.match(reg).map(function(value){return [value , value.replace("{","").replace("}","")];}); console.log(res); > [["{a}","a"],["{b}","b"],["{c}","c"],["{d}","d"]] ちょっと強引な気もしますね。 でもよく考えたら、以下のようにした方が、自然な結果を得られるかもしれませんね。 var str = "{a}-{b}-{c}-{d}"; var reg = RegExp(/\{(.+?)\}/,"g"); var res = str.match(reg).map(function(value){return /\{(.+?)\}/.exec(value)}); console.log(res); > [["{a}","a"],["{b}","b"],["{c}","c"],["{d}","d"]] 結果的に、matchとexecを同時に使うという贅沢なプログラムが出来上がりました。 いや〜言語仕様ってよく出来てますね・・・ そもそも、このコードが標準搭載されていればいいのに・・・

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。