Jest to z pewnością coś, co ma wiele pułapek. Pracowałem z odpowiedzią Paolo Bergantino i zdałem sobie sprawę, że nawet to ma pewne ograniczenia. Zauważyłem, że praca z reprezentacjami dat w postaci ciągów znaków to dobre miejsce na szybkie znalezienie niektórych głównych problemów. Zacznij od ciągu wejściowego, takiego jak ten:
'12-2-2019 5:1:48.670'
i skonfiguruj funkcję Paolo w ten sposób:
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;
}
Chciałem, aby wyrażenie regularne zostało przekazane, aby funkcja była bardziej wielokrotnego użytku, po drugie, chciałem, aby parametr był ciągiem, aby klient nie musiał tworzyć wyrażenia regularnego, ale po prostu dopasować do ciągu, na przykład standardowa metoda klasy narzędziowej typu string.
Teraz widać, że mam do czynienia z problemami z danymi wejściowymi. Z następującymi:
if (typeof re !== "string") {
return 0;
}
Mam zapewnienie, że wejście nie jest coś jak dosłowne 0
, false
, undefined
, lub null
, z których żaden nie są łańcuchami. Ponieważ tych literałów nie ma w ciągu wejściowym, nie powinno być żadnych dopasowań, ale powinny one być zgodne'0'
, co jest ciągiem.
Z następującymi:
re = (re === '.') ? ('\\' + re) : re;
Mam do czynienia z faktem, że konstruktor RegExp zinterpretuje (myślę, że błędnie) ciąg '.'
jako dopasowujący wszystkie znaki\.\
Wreszcie, ponieważ używam konstruktora RegExp, muszę nadać mu 'g'
flagę globalną, aby zliczał wszystkie dopasowania, a nie tylko pierwsze, podobnie jak sugestie w innych postach.
Zdaję sobie sprawę, że to bardzo późna odpowiedź, ale może być pomocna dla kogoś, kto się tu potyka. BTW, oto wersja 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;
}