[解決済み] JavaScriptの正規表現でマッチしたグループにアクセスするにはどうすればよいですか?
質問
を使って文字列の一部にマッチさせたい。 正規表現 で括られた部分文字列にアクセスします。
var myString = "something format_abc"; // I want "abc"
var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);
console.log(arr); // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]); // Prints: undefined (???)
console.log(arr[0]); // Prints: format_undefined (!!!)
何が間違っているのでしょうか?
上記の正規表現のコードには何の問題もないことがわかりました。私が実際にテストしていた文字列はこれです。
"date format_%A"
"%A"が未定義であるという報告は非常に奇妙な動作に思えますが、この質問とは直接関係がないので、新しい質問を開きました。 JavaScriptで、マッチした部分文字列が "undefined"を返すのはなぜですか? .
という問題がありました。
console.log
のようにパラメータを受け取ります。
printf
ステートメントを使用しており、私がログを記録していた文字列 (
"%A"
には特殊な値があり、次のパラメータの値を探そうとしていました。
解決方法は?
このようにキャプチャリンググループにアクセスすることができます。
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var myRegexp = new RegExp("(?:^|\s)format_(.*?)(?:\s|$)", "g");
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
また、複数のマッチングがある場合は、それらを繰り返し処理することができます。
var myString = "something format_abc";
var myRegexp = new RegExp("(?:^|\s)format_(.*?)(?:\s|$)", "g");
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}
編集:2019-09-10
ご覧のように、複数のマッチを反復処理する方法はあまり直感的ではありませんでした。そこで提案されたのが
String.prototype.matchAll
メソッドです。この新しいメソッドは
ECMAScript 2020 仕様
. これは、きれいなAPIを提供し、複数の問題を解決します。主要なブラウザやJSエンジンへの搭載が開始されている。
Chrome 73+ / Node 12+
とFirefox 67+に対応しました。
このメソッドはイテレータを返すので、以下のように使用します。
const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
for (const match of matches) {
console.log(match);
console.log(match.index)
}
イテレータを返すので、遅延処理と言える。これは、特に大量のキャプチャグループや非常に大きな文字列を扱う場合に有効である。しかし、もし必要なら、結果は
スプレッド構文
または
Array.from
メソッドを使用します。
function getFirstGroup(regexp, str) {
const array = [...str.matchAll(regexp)];
return array.map(m => m[1]);
}
// or:
function getFirstGroup(regexp, str) {
return Array.from(str.matchAll(regexp), m => m[1]);
}
とりあえず、この提案がもっと広く支持されるようになるまでの間は 公式shimパッケージ .
また、このメソッドの内部動作はシンプルです。ジェネレーター関数を使った同等の実装は以下のようになる。
function* matchAll(str, regexp) {
const flags = regexp.global ? regexp.flags : regexp.flags + "g";
const re = new RegExp(regexp, flags);
let match;
while (match = re.exec(str)) {
yield match;
}
}
元の正規表現のコピーが作成されます。
lastIndex
プロパティを使用します。
また、正規表現に グローバル のフラグを立てて、無限ループを回避しています。
また、このStackOverflowの質問でさえも、参照されたのは 提案の議論 .
関連
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
[解決済み】Node.jsで "Cannot find module "エラーを解決するには?
-
[解決済み] 正規表現で変数を使うには?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptでメールアドレスを検証するのに最適な方法は何ですか?
-
[解決済み] 単語を含まない行にマッチする正規表現
-
[解決済み] JavaScriptでタイムスタンプを取得する方法は?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vue Element-uiは、アイコンを追加するためのツリーコントロールノードを詳細に実装しています。
-
Vueはランニングライト形式のテキストを水平方向にスクロールする機能を実装している
-
WeChatアプレット用ユニアプリによるグローバルシェアリング
-
vueのグローバルがscss(mixin)を導入。
-
Vueのフィルタの説明
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み】JavaScriptの配列でforEachが関数でない不具合
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】<select>で現在選択されている<option>をJavaScriptで取得するにはどうすればよいですか?
-
nullのプロパティinnerHTMLを読み取れません エラーメッセージ