regex JavaScript中正则表达式的匹配计数

8tntrjer  于 2023-08-08  发布在  Java
关注(0)|答案(9)|浏览(98)

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

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

字符串
由于某些未知的原因,它总是返回1。上述说法有什么问题?我已经解决了以下问题:

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

vybvopom

vybvopom1#

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

原始答案

初始代码的问题是缺少了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

nbewdwxp

nbewdwxp2#

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

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

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

return count;

字符串

qpgpyjmq

qpgpyjmq3#

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

字符串
基于https://stackoverflow.com/a/48195124/16777,但修复为实际工作在零结果的情况下。

xtfmy6hx

xtfmy6hx4#

这里有一个类似于@Paolo贝尔甘蒂诺的答案的解决方案,但使用了现代运营商。我会在下面解释。

const matchCount = (str, re) => {
      return str?.match(re)?.length ?? 0;
    };

    // usage
    
    let numSpaces = matchCount(undefined, /\s/g);
    console.log(numSpaces); // 0
    numSpaces = matchCount("foobarbaz", /\s/g);
    console.log(numSpaces); // 0
    numSpaces = matchCount("foo bar baz", /\s/g);
    console.log(numSpaces); // 2

字符串
?.optional chaining operator。它允许你将调用链到你想要的深度,而不必担心是否有一个undefined/null。将str?.match(re)视为

if (str !== undefined && str !== null) {
    return str.match(re);
} else {
    return undefined;
}


这与@Paolo贝尔甘蒂诺的略有不同。他们的信是这样写的:(str || '')。这意味着如果strfalsy,则返回''。0是假的。document.all是假的。在我看来,如果有人把这些作为字符串传递给这个函数,那可能是因为程序员的错误。因此,我宁愿被告知我正在做一些不明智的事情,而不是解决为什么我总是得到长度为0的问题。
??nullish coalescing operator。可以把它想象成||,但更具体一些。如果||的左手计算结果为 falsy,则执行右侧。但是??只有在左侧为undefined或null时才会执行。
请记住,?.length ?? 0中的null合并运算符将返回与使用?.length || 0相同的内容。不同的是,如果length返回0,它将不会执行右边的...但无论使用||还是??,结果都是0。
老实说,在这种情况下,我可能会将其更改为||,因为更多的JavaScript开发人员熟悉该操作符。也许有人可以启发我在这种情况下??||的好处,如果有的话。
最后,我修改了签名,使函数可以用于任何正则表达式。
这里有一个typescript版本:

const matchCount = (str: string, re: RegExp) => {
      return str?.match(re)?.length ?? 0;
    };

7eumitmz

7eumitmz6#

这肯定是有很多陷阱的东西。我正在研究保罗·贝尔甘蒂诺的答案,并意识到即使这样也有一些局限性。我发现使用日期的字符串表示是快速找到一些主要问题的好地方。以如下的输入字符串开始:第一个月
并像这样设置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;
}

np8igboo

np8igboo7#

这似乎很好地解决了,但我还没有看到这个版本,这可能是一个更可读的,并保持在一些代码库的风格:

const numberOfResults = [...str.matchAll(/YOUR_REGEX/g)].length;

字符串

46scxncf

46scxncf8#

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

const countMatches = (exp, str) => str.match(exp)?.length ?? 0;

字符串
必须将exp作为RegExp传递,将str作为String传递。

jexiocij

jexiocij9#

这样怎么样

function isint(str){
    if(str.match(/\d/g).length==str.length){
        return true;
    }
    else {
         return false
    }
}

字符串

相关问题