Javascriptで正規表現の一致数を数える


98

テキストのチャンク内のスペース/タブ/改行の数を数える正規表現を書きたかった。だから私は単純に次のように書いた:-

numSpaces : function(text) { 
    return text.match(/\s/).length; 
}

いくつかの不明な理由により、常に戻ります1。上記のステートメントの問題は何ですか?私はそれ以来、次の問題を解決しました:-

numSpaces : function(text) { 
    return (text.split(/\s/).length -1); 
}

回答:


191

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

5
これは、入力に少なくとも1つのスペースがある限り機能します。それ以外の場合、match()はうっとうしくnullを返します。
スフィンク2011

3
sfinkは右である、あなたは間違いなく確認したい試合()返された場合はnull:var result = text.match(/\s/g); return result ? result.length : 0;
グラダブル

37
:あなたはまた、この構成を使用することにより、ヌルから守ることができます( str.match(...) || [] ).length
a'r

11

以前の回答で述べたようにを使用RegExp.exec()してすべての一致を反復し、各発生をカウントできます。全体的にはを使用するよりも約20%遅いため、利点はメモリのみに限定されますString.match()

var re = /\s/g,
count = 0;

while (re.exec(text) !== null) {
    ++count;
}

return count;


2

('my string'.match(/\s/g) || []).length;


1
私はあなたが|| []間違った場所に置いたと思います、それはそうあるべきです('my string'.match(/\s/g) || []).length
woojoo666

0

これは確かに多くの落とし穴があります。私はパオロベルガンティーノの答えを使用していて、それでもいくつかの制限があることに気づきました。日付の文字列表現を使用すると、いくつかの主要な問題をすばやく見つけるのに適した場所であることがわかりました。次のような入力文字列から始めます。 '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;
}

私は、入力がリテラルのようなものではないことを保証しています0falseundefined、または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;
}

-2

どうですか

function isint(str){
    if(str.match(/\d/g).length==str.length){
        return true;
    }
    else {
         return false
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.