Zählen Sie die Anzahl der Übereinstimmungen eines regulären Ausdrucks in Javascript
98
Ich wollte einen regulären Ausdruck schreiben, um die Anzahl der Leerzeichen / Tabulatoren / Zeilenumbrüche in einem Textblock zu zählen. Also schrieb ich naiv folgendes: -
// THIS IS WHAT YOU NEEDconst count =(str)=>{const re =/YOUR_PATTERN_HERE/greturn((str ||'').match(re)||[]).length}
Für diejenigen, die hier angekommen sind und nach einer generischen Methode suchen, um die Anzahl der Vorkommen eines Regex-Musters in einer Zeichenfolge zu zählen, und nicht möchten, dass es fehlschlägt, wenn es keine Vorkommen gibt, ist dieser Code genau das, was Sie brauchen. Hier ist eine Demonstration:
/*
* Example
*/const count =(str)=>{const re =/[a-z]{3}/greturn((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'`)
Dies funktioniert, solange Sie mindestens ein Leerzeichen in Ihrer Eingabe haben. Andernfalls gibt match () ärgerlicherweise null zurück.
Sfink
3
sfink ist richtig, Sie möchten auf jeden Fall überprüfen, ob match () null zurückgegeben hat:var result = text.match(/\s/g); return result ? result.length : 0;
Gras Double
37
: Sie können auch mit Hilfe dieser Konstruktion gegen die Null schützen( str.match(...) || [] ).length
a'r
11
Wie in meiner früheren Antwort erwähnt , können Sie RegExp.exec()alle Übereinstimmungen durchlaufen und jedes Vorkommen zählen. Der Vorteil ist nur auf den Speicher beschränkt, da er insgesamt etwa 20% langsamer ist als die Verwendung String.match().
var re =/\s/g,
count =0;while(re.exec(text)!==null){++count;}return count;
Ich denke, Sie setzen das || []an die falsche Stelle, es sollte sein('my string'.match(/\s/g) || []).length
woojoo666
0
Dies ist sicherlich etwas, das viele Fallen hat. Ich habe mit Paolo Bergantinos Antwort gearbeitet und festgestellt, dass selbst das einige Einschränkungen hat. Ich fand die Arbeit mit Zeichenfolgendarstellungen von Daten ein guter Ort, um schnell einige der Hauptprobleme zu finden. Beginnen Sie mit einer Eingabezeichenfolge wie folgt:
'12-2-2019 5:1:48.670'
und richten Sie die Funktion von Paolo folgendermaßen ein:
function count(re, str){if(typeof re !=="string"){return0;}
re =(re ==='.')?('\\'+ re): re;var cre =newRegExp(re,'g');return((str ||'').match(cre)||[]).length;}
Ich wollte, dass der reguläre Ausdruck übergeben wird, damit die Funktion wiederverwendbarer ist. Zweitens wollte ich, dass der Parameter eine Zeichenfolge ist, damit der Client den regulären Ausdruck nicht erstellen muss, sondern einfach mit der Zeichenfolge übereinstimmt eine Standard-String-Utility-Klassenmethode.
Hier können Sie sehen, dass ich Probleme mit der Eingabe habe. Mit den folgenden:
if(typeof re !=="string"){return0;}
Ich bin sicher , dass die Eingabe nicht so etwas wie die wörtlichen 0, false, undefined, oder null, von denen keine Strings sind. Da diese Literale nicht in der Eingabezeichenfolge enthalten sind, sollte es keine Übereinstimmungen geben, aber es sollte übereinstimmen '0', was eine Zeichenfolge ist.
Mit den folgenden:
re =(re ==='.')?('\\'+ re): re;
Ich habe es damit zu tun, dass der RegExp-Konstruktor (ich denke falsch) die Zeichenfolge '.'als All-Character-Matcher interpretiert\.\
Da ich den RegExp-Konstruktor verwende, muss ich ihm das globale 'g'Flag geben, damit alle Übereinstimmungen gezählt werden, nicht nur die erste, ähnlich wie in den Vorschlägen in anderen Posts.
Mir ist klar, dass dies eine extrem späte Antwort ist, aber es könnte hilfreich sein, wenn jemand hier entlang stolpert. Übrigens ist hier die TypeScript-Version:
function count(re: string, str: string): number {if(typeof re !=='string'){return0;}
re =(re ==='.')?('\\'+ re): re;const cre =newRegExp(re,'g');return((str ||'').match(cre)||[]).length;}
var result = text.match(/\s/g); return result ? result.length : 0;
( str.match(...) || [] ).length
Wie in meiner früheren Antwort erwähnt , können Sie
RegExp.exec()
alle Übereinstimmungen durchlaufen und jedes Vorkommen zählen. Der Vorteil ist nur auf den Speicher beschränkt, da er insgesamt etwa 20% langsamer ist als die VerwendungString.match()
.quelle
Basierend auf https://stackoverflow.com/a/48195124/16777, aber behoben, um tatsächlich im Fall ohne Ergebnisse zu funktionieren.
quelle
('my string'.match(/\s/g) || []).length;
quelle
|| []
an die falsche Stelle, es sollte sein('my string'.match(/\s/g) || []).length
Dies ist sicherlich etwas, das viele Fallen hat. Ich habe mit Paolo Bergantinos Antwort gearbeitet und festgestellt, dass selbst das einige Einschränkungen hat. Ich fand die Arbeit mit Zeichenfolgendarstellungen von Daten ein guter Ort, um schnell einige der Hauptprobleme zu finden. Beginnen Sie mit einer Eingabezeichenfolge wie folgt:
'12-2-2019 5:1:48.670'
und richten Sie die Funktion von Paolo folgendermaßen ein:
Ich wollte, dass der reguläre Ausdruck übergeben wird, damit die Funktion wiederverwendbarer ist. Zweitens wollte ich, dass der Parameter eine Zeichenfolge ist, damit der Client den regulären Ausdruck nicht erstellen muss, sondern einfach mit der Zeichenfolge übereinstimmt eine Standard-String-Utility-Klassenmethode.
Hier können Sie sehen, dass ich Probleme mit der Eingabe habe. Mit den folgenden:
Ich bin sicher , dass die Eingabe nicht so etwas wie die wörtlichen
0
,false
,undefined
, odernull
, von denen keine Strings sind. Da diese Literale nicht in der Eingabezeichenfolge enthalten sind, sollte es keine Übereinstimmungen geben, aber es sollte übereinstimmen'0'
, was eine Zeichenfolge ist.Mit den folgenden:
Ich habe es damit zu tun, dass der RegExp-Konstruktor (ich denke falsch) die Zeichenfolge
'.'
als All-Character-Matcher interpretiert\.\
Da ich den RegExp-Konstruktor verwende, muss ich ihm das globale
'g'
Flag geben, damit alle Übereinstimmungen gezählt werden, nicht nur die erste, ähnlich wie in den Vorschlägen in anderen Posts.Mir ist klar, dass dies eine extrem späte Antwort ist, aber es könnte hilfreich sein, wenn jemand hier entlang stolpert. Übrigens ist hier die TypeScript-Version:
quelle
wie wäre es so
quelle