我一直在练习使用正则表达式更加舒服,但我很难理解为什么我写的这个函数不起作用。我写了一个简单的函数来计算单词中重复字母的数量,这似乎有时会起作用,但不会一直有效。
function duplicates(str){
try{
return str.match(/(.)\1+/ig).length;
}catch(e){
return 0;
}
}
根据我所研究的内容,这个陈述应该通过字符串查找,找到一个不止一次重复忽略大小写的字母(或多个字母),并返回匹配字母的长度。如果没有匹配的字母出现,它将返回0.它适用于某些字符串,但不是全部。这是我得到的:
duplicates("abcdef") -> 0 #should return 0
duplicates("Aabccdef") -> 2 #should return 2
duplicates("Mississippi") -> 3 #should return 3
duplicates("Indivisible") -> 0 #should return 1
duplicates("abcabcabc") -> 0 #should return 3
经过进一步检查,似乎当我运行“Mississippi”时,我得到了预期的数字3,但是当我添加.toString()代替.length时,看看我得到的表达式是什么:
ss,ss,pp
我没有计算,应该有。似乎我也不算“不可分割”,并没有在“abcabcabc”中指出任何重复的字母。它似乎无法计算非连续重复,但我无法弄清楚为什么。我确信这是我对正则表达式如何工作的误解,因为我对他们不熟悉,但如果有人能说明为什么会发生这种情况,那就太棒了!
编辑:有没有办法用RegEx做到这一点,还是我需要使用循环?
答案 0 :(得分:2)
就您发布的实际正则表达式而言,它存在一些问题。 (.)\1+
无法正常工作的原因是“第一次匹配”' (\1
)紧跟在匹配组后面跟.
。这意味着在密西西比州的情况下,因为没有连续匹配的字母,所以您的模式与它们不匹配。
作为此问题的替代解决方案,您可以保持简单。对于您的用例,更合理的解决方案是简单地遍历并计算每个字母。
function duplicates(str){
try{
let letters = str.toLowerCase().split('');
let countedLetters = {}
for(let i = 0; i < letters.length; i++) {
countedLetters[letters[i]] = countedLetters[letters[i]] + 1 || 1;
}
return countedLetters;
} catch(e) {
return 0;
}
}
console.log(duplicates('Mississippi'));
&#13;
答案 1 :(得分:1)
你已经接近实现它了,但是因为你在捕获后立即寻找最近被捕获的角色,你不能计算不是邻居的角色。
这个想法是使用积极的前瞻来找到重复的字符,然后省略重复的字符以留下唯一的字符来计算它们。正则表达式:
(.)(?=.*\1)
function duplicates($str) {
return [...new Set($str.toLowerCase().match(/(.)(?=.*\1)/g))].length;
}
console.log(duplicates("abcdef"));
console.log(duplicates("Aabccdef"));
console.log(duplicates("Mississippi"));
console.log(duplicates("Indivisible"));
console.log(duplicates("abcabcabc"));
function _unique(value, index, self) {
return self.indexOf(value) === index;
}
function duplicates($str) {
return ($str.toLowerCase().match(/(.)(?=.*\1)/g) || Array()).filter(_unique).length;
}
console.log(duplicates("abcdef"));
console.log(duplicates("Aabccdef"));
console.log(duplicates("Mississippi"));
console.log(duplicates("Indivisible"));
console.log(duplicates("abcabcabc"));
答案 2 :(得分:0)
你的正则表达式取任何字母,让你说X来自你的单词并且后面引用一个字母来检查它是否相同。您可以使用此可视化工具来了解它正在做什么。它计算第一次出现后紧跟的字符的出现次数。
与您的查询相关联:https://regexper.com/#%2F(.)%5C1%2B%2Fig
链接到网站:https://regexper.com/
答案 3 :(得分:-1)
我没有调查“Indivisible&#39;”中的重复项。
这不是完全答案,因为&#39; abcabcabc&#39;字符串可以划分为子模式,例如&#39; abcabc&#39;从0字符和&#39; abcabc&#39;开始从3个角色开始。
这不是完全答案,但我希望这将是有用的
'olololo'.match(/(.+)(?=(\1))/ig)