回答:
tl; dr:汎用パターンカウンター
// THIS IS WHAT YOU NEED
const count = (str) => {
const re = /YOUR_PATTERN_HERE/g
return ((str || '').match(re) || []).length
}
ここに到着して、文字列内の正規表現パターンの出現回数をカウントする一般的な方法を探していて、出現がゼロの場合に失敗しないようにするには、このコードが必要です。ここにデモンストレーションがあります:
/*
* Example
*/
const count = (str) => {
const re = /[a-z]{3}/g
return ((str || '').match(re) || []).length
}
const str1 = 'abc, def, ghi'
const str2 = 'ABC, DEF, GHI'
console.log(`'${str1}' has ${count(str1)} occurrences of pattern '/[a-z]{3}/g'`)
console.log(`'${str2}' has ${count(str2)} occurrences of pattern '/[a-z]{3}/g'`)
元の回答
最初のコードの問題は、グローバル識別子がないことです:
>>> 'hi there how are you'.match(/\s/g).length;
4
g
正規表現の一部がなければ、最初の出現にのみ一致し、そこで停止します。
また、正規表現は連続するスペースを2回カウントすることに注意してください。
>>> 'hi there'.match(/\s/g).length;
2
それが望ましくない場合は、次のようにすることができます。
>>> 'hi there'.match(/\s+/g).length;
1
var result = text.match(/\s/g); return result ? result.length : 0;
( str.match(...) || [] ).length
以前の回答で述べたように、を使用RegExp.exec()
してすべての一致を反復し、各発生をカウントできます。全体的にはを使用するよりも約20%遅いため、利点はメモリのみに限定されますString.match()
。
var re = /\s/g,
count = 0;
while (re.exec(text) !== null) {
++count;
}
return count;
(('a a a').match(/b/g) || []).length; // 0
(('a a a').match(/a/g) || []).length; // 3
https://stackoverflow.com/a/48195124/16777に基づいていますが、結果がゼロの場合に実際に機能するように修正されています。
これは確かに多くの落とし穴があります。私はパオロベルガンティーノの答えを使用していて、それでもいくつかの制限があることに気づきました。日付の文字列表現を使用すると、いくつかの主要な問題をすばやく見つけるのに適した場所であることがわかりました。次のような入力文字列から始めます。
'12-2-2019 5:1:48.670'
次のようにPaoloの機能を設定します。
function count(re, str) {
if (typeof re !== "string") {
return 0;
}
re = (re === '.') ? ('\\' + re) : re;
var cre = new RegExp(re, 'g');
return ((str || '').match(cre) || []).length;
}
正規表現を渡して、関数をより再利用できるようにしたいと思いました。次に、パラメーターを文字列にして、クライアントが正規表現を作成する必要がなく、単に文字列と一致するようにしました。標準の文字列ユーティリティクラスメソッド。
ここで、入力に関する問題を処理していることがわかります。以下の場合:
if (typeof re !== "string") {
return 0;
}
私は、入力がリテラルのようなものではないことを保証しています0
、false
、undefined
、またはnull
、いずれも文字列であるのは。これらのリテラルは入力文字列にないため、一致する必要はありません'0'
が、文字列であると一致する必要があります。
以下の場合:
re = (re === '.') ? ('\\' + re) : re;
RegExpコンストラクターが文字列'.'
をすべての文字マッチャーとして解釈する(間違っていると思います)という事実に対処しています\.\
最後に、RegExpコンストラクターを使用している'g'
ため、他の投稿の提案と同様に、最初の一致だけでなく、すべての一致をカウントするようにグローバルフラグを与える必要があります。
これは非常に遅い回答だと思いますが、ここで偶然見つけた人には役立つかもしれません。ところで、ここにTypeScriptのバージョンがあります。
function count(re: string, str: string): number {
if (typeof re !== 'string') {
return 0;
}
re = (re === '.') ? ('\\' + re) : re;
const cre = new RegExp(re, 'g');
return ((str || '').match(cre) || []).length;
}