正規表現 を使用して文字列の一部を照合してから、その括弧で囲まれた部分文字列にアクセスします。
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 match = myRegexp.exec(myString);
console.log(match[1]); // abc
そして複数の一致がある場合は、それらを繰り返すことができます。
var myString = "something format_abc";
var myRegexp = /(?:^|\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);
}
これは、マッチごとに n 番目のキャプチャグループを取得するために使用できる方法です。
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.Push(match[index]);
}
return matches;
}
// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);
var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);
\b
はまったく同じものではありません。 (これは--format_foo/
では動作しますが、format_a_b
では動作しません)しかし、私はあなたの表現に代わるものを見せたかったのです。もちろん、match
呼び出しは重要なことです。
上記の複数一致の括弧の例に関して、私が欲しいものを手に入れなかった後、私はここで答えを探していました:
var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);
上記のwhileと.Push()でやや複雑な関数呼び出しを見た後、代わりにmystring.replace()で問題を非常にエレガントに解決できることがわかりました(置き換えは重要ではなく、実行もされません2番目のパラメータに対するCLEANの組み込み再帰関数呼び出しオプションは、次のとおりです。
var yourstring = 'something format_abc something format_def something format_ghi';
var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.Push(p1); } );
この後、私は二度とほとんど何もしないために.match()を使うつもりはないと思います。
あなたの文法はおそらく保つのが最善ではないでしょう。 FF/Geckoは、RegExpをFunctionの拡張として定義しています。
(FF2はtypeof(/pattern/) == 'function'
まで行きました)
これはFFに固有のもののようです - IE、Opera、そしてChromeはすべて例外を投げます。
代わりに、RegExp#exec
またはString#match
のいずれかの方法を使用してください。
同じ結果が得られます。
var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";
regex(input); //=> [" format_abc", "abc"]
regex.exec(input); //=> [" format_abc", "abc"]
input.match(regex); //=> [" format_abc", "abc"]
大事なことを言い忘れたが、私は私のためにうまく働いた1行のコードを見つけた(JS ES6):
let reg = /#([\S]+)/igm; // Get hashtags.
let string = 'mi alegría es total! ✌????\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';
let matches = (string.match(reg) || []).map(e => e.replace(reg, '$1'));
console.log(matches);
これは戻ります:
['fiestasdefindeaño', 'PadreHijo', 'buenosmomentos', 'france', 'paris']
someString.match(regexPattern)
。/format_(.*?)/g
、ここで(.*?)
は一致グループです。)これらは 一致パターン の中にあります。マッチしたグループにアクセスするには、それぞれのマッチしたパターンに、マッチを反復する関数など)が必要です。これを実行する方法はいくつかあります。他の回答の多くが示すように、他のほとんどの回答ではwhileループを使用してすべてのマッチしたパターンを繰り返します)が、このアプローチの潜在的な危険性は知っています。代わりにnew RegExp()
と照合する必要があります。これは、.exec()
メソッドがジェネレータ関数 - )のように振る舞うためです。これはmatch があるたびに停止しますが、.lastIndex
はそのまま続けます。次の.exec()
呼び出しにあります。
以下は、すべてのマッチしたパターン、それぞれの_ searchString
name__がすべてのマッチしたグループを含む)の_ Array
name__である)のmatch
name__を返す関数Array
name__の例です。単純なfor
name __-ループを使用したArray.prototype.map()
関数と、より高性能な方法の両方。
これらは基本的に高速のforEach
name __-ループではなくfor
name __-ループを実装するため、これらのパフォーマンスは低下します。
// Concise ES6/ES2015 syntax
const searchString =
(string, pattern) =>
string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
// Or if you will, with ES5 syntax
function searchString(string, pattern) {
return string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
let result = [];
const matches = string.match(new RegExp(pattern.source, pattern.flags));
for (let i = 0; i < matches.length; i++) {
result.Push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
};
// Same thing, but with ES5 syntax
function searchString(string, pattern) {
var result = [];
var matches = string.match(new RegExp(pattern.source, pattern.flags));
for (var i = 0; i < matches.length; i++) {
result.Push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
これらの代替案を他の回答で前述したものと比較することはまだしていませんが、このアプローチが他のものよりもパフォーマンスが低く、フェイルセーフが低いとは思えません。
exec
メソッドを呼び出す必要はありません。文字列に対して直接 "match"メソッドを使うことができます。括弧を忘れないでください。
var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...
位置0には、すべての結果を含むストリングがあります。位置1は最初の一致を括弧で表し、位置2は2番目の一致を括弧で分離したものです。入れ子の括弧は扱いにくいので注意してください。
一対の括弧がある場合にのみ実用的なワンライナー。
while ( ( match = myRegex.exec( myStr ) ) && matches.Push( match[1] ) ) {};
あなたのコードを使う:
console.log(arr[1]); // prints: abc
console.log(arr[0]); // prints: format_abc
編集:それが重要ならばSafari 3。
String#matchAll
( Stage 3 Draft/2018年12月7日の提案 を参照)、マッチオブジェクト内のすべてのグループへのアクセスを単純化します(Group 0が完全マッチであることに注意) groupsはパターン内のキャプチャグループに対応します。
matchAll
が利用可能であれば、while
ループや/g
..でexec
を回避することができます。代わりに、matchAll
を使用すると、より便利なfor...of
、 array spread 、またはArray.from()
コンストラクト
このメソッドは、C#のRegex.Matches
、Pythonのre.finditer
、PHPのpreg_match_all
と同様の出力を生成します。
JSデモ(Google Chrome 73.0.3683.67(公式ビルド)、ベータ版(64ビット)でテスト済み)を参照してください。
var myString = "key1:value1, key2-value2!!@key3=value3";
var matches = myString.matchAll(/(\w+)[:=-](\w+)/g);
console.log([...matches]); // All match with capturing group values
console.log([...matches])
ショー
また、マッチ値または特定のグループ値を取得することもできます。
let matchData = "key1:value1, key2-value2!!@key3=value3".matchAll(/(\w+)[:=-](\w+)/g)
var matches = [...matchData]; // Note matchAll result is not re-iterable
console.log(Array.from(matches, m => m[0])); // All match (Group 0) values
// => [ "key1:value1", "key2-value2", "key3=value3" ]
console.log(Array.from(matches, m => m[1])); // All match (Group 1) values
// => [ "key1", "key2", "key3" ]
_ note _ : ブラウザの互換性 の詳細を参照してください。
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.Push(match[index]);
}
return matches;
}
// Example :
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.Push(match[index]);
}
return matches;
}
// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);
複数の一致を解析するために明示的なループは実際に必要ありません— String.prototype.replace(regex, func)
で説明されているように、2番目の引数として置換関数を渡します。
var str = "Our chief weapon is {1}, {0} and {2}!";
var params= ['surprise', 'fear', 'ruthless efficiency'];
var patt = /{([^}]+)}/g;
str=str.replace(patt, function(m0, m1, position){return params[parseInt(m1)];});
document.write(str);
m0
引数は、完全に一致した部分文字列{0}
、{1}
などを表します。m1
は、最初に一致したグループ、つまり0
最初の一致。 position
は、一致するグループが見つかった文字列内の開始インデックスです。この場合は未使用です。
/*Regex function for extracting object from "window.location.search" string.
*/
var search = "?a=3&b=4&c=7"; // Example search string
var getSearchObj = function (searchString) {
var match, key, value, obj = {};
var pattern = /(\w+)=(\w+)/g;
var search = searchString.substr(1); // Remove '?'
while (match = pattern.exec(search)) {
obj[match[0].split('=')[0]] = match[0].split('=')[1];
}
return obj;
};
console.log(getSearchObj(search));
バックスラッシュとそれに続く一致グループの番号を使用して、正規表現で一致グループにアクセスできます。
/([a-z])\1/
最初のグループ([a-z])と一致することを表すコード\ 1
Es2018では、名前付きグループを使ってString.match()
を使えるようになりました。正規表現をより明確にしようとしていました。
const url =
'https://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);
そして、あなたは何かのようになるでしょう
{protocol: "https"、hostname: "stackoverflow.com"、pathname: "questions/432493/javascriptの正規表現に一致するグループにアクセスする方法"、querystring: " some = parameter "}
すべてのグループオカレンスを取得
let m=[], s = "something format_abc format_def format_ghi";
s.replace(/(?:^|\s)format_(.*?)(?:\s|$)/g, (x,y)=> m.Push(y));
console.log(m);