计算Javascript中正则表达式的匹配数

时间:2009-07-02 06:15:53

标签: javascript regex

我想写一个正则表达式来计算一大块文本中的空格/制表符/换行符的数量。所以我天真地写了以下内容: -

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

由于某些未知原因,它始终返回1。上述陈述有什么问题?我已经解决了以下问题: -

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

7 个答案:

答案 0 :(得分:159)

tl; dr:Generic Pattern Counter

// 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'`)

原始答案

初始代码的问题在于您错过了global identifier

>>> 'hi there how are you'.match(/\s/g).length;
4

如果没有正则表达式的g部分,它只会匹配第一次出现并停在那里。

另请注意,您的正则表达式将连续计算两次空格:

>>> 'hi  there'.match(/\s/g).length;
2

如果不希望这样,你可以这样做:

>>> 'hi  there'.match(/\s+/g).length;
1

答案 1 :(得分:9)

my earlier answer中所述,您可以使用RegExp.exec()迭代所有匹配并计算每次出现的次数;优势仅限于内存,因为总体上它比使用String.match()慢约20%。

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

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

return count;

答案 2 :(得分:1)

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

答案 3 :(得分:1)

(('a a a').match(/b/g) || []).length; // 0
(('a a a').match(/a/g) || []).length; // 3

基于https://stackoverflow.com/a/48195124/16777,但已固定为在零结果情况下实际工作。

答案 4 :(得分:0)

这肯定有很多陷阱。我正在研究Paolo Bergantino的答案,并意识到即使那样也有一些局限性。我发现使用日期的字符串表示形式是快速找到一些主要问题的好地方。从这样的输入字符串开始: '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;
}

我确保输入的内容不是文字0falseundefinednull之类的东西,都不是字符串。由于这些文字不包含在输入字符串中,因此不应有匹配项,但应与'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;
}

答案 5 :(得分:0)

使用现代语法避免了创建虚拟数组来计算长度 0 的需要

AS400WriteRefundLine as400WriteRefundLine

必须将 const countMatches = (exp, str) => str.match(exp)?.length ?? 0; 传递为 exp 并将 RegExp 传递为 str

答案 6 :(得分:-1)

这样怎么样

$('#calendar').fullCalendar({
    eventResize: function(event, delta, revertFunc) {
        $('.popover.fade.top').remove();
    },
...