0

例如:

let a ='caaab'

我需要'aa'出现的次数,所以当我写的时候,

a.match(/aa/g)

它返回的['aa']是错误的,

那么我能得到任何其他表达['aa','aa']吗?

4

2 回答 2

2

我不知道是否可以仅通过使用正则表达式来实现它,但您可以编写一个函数,例如:

function countOccurencies(text, pattern) {
  let index = 0;
  let count = 0;
  let find;
  while((find = text.substr(index).search(pattern)) >= 0) {
    index += find + 1;
    count++;
  }
  return count;
}

// You can use it like this:
let occ;
occ = countOccurencies('caaab', /aa/g); // 2
occ = countOccurencies('caaab', 'aa');  // 2
于 2021-01-27T19:22:37.553 回答
0

您可以使用以下表达式:/(.)(?=\1)/g

简短说明:

  • (.)是一个捕获组;它捕获除换行符以外的任何字符
  • \1是对第一个捕获组(的(.))的反向引用
  • (?=\1)为该反向引用创建一个积极的前瞻\1(不消耗字符)
  • 正则表达式末尾的g选项表示应返回所有匹配项,而不仅仅是第一个匹配项。

最终的正则表达式匹配结果将包含后跟相同字符的所有字符。

let regex = /(.)(?=\1)/g
let a1 = 'caaab'
let r1 = a1.match(regex) // [ 'a', 'a' ]
let a2 = 'caaabbcdd'
let r2 = a2.match(regex) // [ 'a', 'a', 'b', 'd' ]

在您的正则表达式匹配中,您不会得到双倍的字符,只有单个字符。但是使用该Array.prototype.map函数可以很容易地将它们加倍,因为您确定它们后面总是跟在搜索字符串中的相同字符。

let regex = /(.)(?=\1)/g
let a1 = 'caaab'
let r1 = a1.match(regex).map(ch => ch + ch) // [ 'aa', 'aa' ]
let a2 = 'caaabbcdd'
let r2 = a2.match(regex).map(ch => ch + ch) // [ 'aa', 'aa', 'bb', 'dd' ]

换行符

捕获组(.)不匹配双倍换行符。如果您还想包含双倍换行符,您可以将它们添加到捕获组中,如下所示(.|\n):生成的代码如下所示:

let regex = /(.|\n)(?=\1)/g
let a = 'caaab\nbbc\n\nddd'
let r = a.match(regex).map(ch => ch + ch) // [ 'aa', 'aa', 'bb', '\n\n', 'dd', 'dd' ]

关于性能和可维护性的说明

正则表达式可能会造成严重的性能损失。此外,它们难以阅读和理解。由于我的回答可能会为您使用正则表达式的问题提供有效的解决方案,因此我建议不要使用它。创建一个提供相同结果的小函数可能会更高效且更易于理解,从而简化了未来的维护。

function getDoubleChars(searchString, includeNewlines = false) {
  let result = []
  let previousChar = ''

  for (let char of searchString) {
    if (char === previousChar) {
      if (char !== '\n' || includeNewlines) {
        result.push(char + char)
      }
    }

    previousChar = char
  }

  return result;
}

let a = 'caaab\nbbc\n\nddd'
let r = getDoubleChars(a) // [ 'aa', 'aa', 'bb', 'dd', 'dd' ]
let r = getDoubleChars(a, true) // [ 'aa', 'aa', 'bb', '\n\n', 'dd', 'dd' ]
于 2021-01-28T07:25:17.700 回答