RegExp detect multiple single-letter instances in a row?

时间:2015-07-29 00:41:53

标签: javascript regex

So I'm making a program to parse twitch chat, and I'm wondering if there's a way I can use regex to parse the following into the desired result:

if(cond1) { par(mfrow=c(3,1)) plot1 plot2 plot3 } else { par(mfrow=c(3,2)) plot1 plot2 plot3 plot4 plot5 plot6 }

So far, the code I have is "f o o b a r" into "foobar" and this works to an extent, but consider the following situation:

/(?:(\w)\s){3,}/g captures "T" (the last letter in "FrankerZ R I O T FrankerZ") and selects "R I O T"

What I would want for this is to figure out how to detect if there is a single letter with a space before and after it, and if there are at minimum 3 of those in a row (so "Z R I O T" isn't selected as "test a b test", only captures if there are 3+)

Any help? Thanks!

7 个答案:

答案 0 :(得分:3)

尝试此模式:/(?:\b\w(?:\s|$)){3,}/g

这使用单词边界元字符\b,因此您可以获得正确的全字匹配,而不是您使用FrankerZ看到的部分匹配。此外,\s|$位解决了在没有空格后丢失的最后一个字母,例如R I O T中的“T”。

示例:

var inputs = [
  "R I",
  "R I O T",
  "FrankerZ R I O T FrankerZ",
  "f o o b a r"
];

var re = /(?:\b\w(?:\s|$)){3,}/g;

inputs.forEach(function(s) {
  var match = s.match(re);
  if (match) {
    var result = match[0].replace(/\s/g, '');
    console.log('Original: ' + s);
    console.log('Result: ' + result);
  } else {
    console.log('No match: ' + s);
  }
});

演示:JSBin

编辑:更新以涵盖3个以上的单个字母和不匹配的示例。

答案 1 :(得分:1)

感谢Sam Burns建议使用\ b。对我有用的是:

/\b((?:\w ?\b){3,})/g

这将选择以下内容:

来自H Y P E

FrankerZ H Y P E FrankerZ, 和 f o o b a r(没有结束或以空格字符开头,也给了我一些问题)

当我只想首先检查空格字符时,指定文字空间" "字符而不是\s对于避免换行和其他实例也很重要。

如果没有空格替换它,我只需.replace(" ","")即可获得我想要的确切结果。再次感谢大家的帮助:)

答案 2 :(得分:1)

以下是如何使用匹配Javascript replace with reference to matched group?

替换的好参考

所以你可以这样做:

glob

请参阅demo

答案 3 :(得分:0)

您只能使用正则表达式来解决整个问题。

也就是说,没有正则表达式可以执行以下所有操作:

  • 不选择任何您对
  • 不感兴趣的内容
  • 捕获您对
  • 感兴趣的所有内容
  • 捕获可变数量的匹配

最后一项要求 - 可变数量的捕获 - 是最重要的要求。 StackOverflow用户Tomalak described the situation quite well

  

通过括号定义组。您的匹配结果将包含与正则表达式中的括号对一样多的组(除了修改后的括号,如(?:...),这些括号不会计入匹配组)。想要在匹配结果中进行两次单独的小组赛吗?在正则表达式中定义两个单独的组。

     

如果某个群组可以多次匹配,则群组的值将是最后匹配的值。该组的所有先前匹配事件将被其上一次匹配覆盖。

但是,您仍然可以让正则表达式执行很多工作,例如使用\b边界词锚点。这很像你所描述的"它之前和之后的空间"但是更接近你想要的东西,因为它与空间本身不匹配(甚至不需要)。

> "R I O T".match(/\b\w\b/g)
["R", "I", "O", "T"]
> "FrankerZ R FrankerZ I FrankerZ O FrankerZ T".match(/\b\w\b/g)
["R", "I", "O", "T"]

你想要量化,当然这个正则表达式不包含量词:

> "test a b test".match(/\b\w\b/g)
["a", "b"]

但你可以在正则表达式之外执行此操作:

var individual_letters_re = /\b\w\b/g;

function hiddenWord(sentence) {
    letters = sentence.match(individual_letters_re);
    if (letters && letters.length >= 3) {
        return letters.join("");
    }
    return "";
}

> hiddenWord("R I O T")
"RIOT"
> hiddenWord("FrankerZ R FrankerZ I FrankerZ O FrankerZ T")
"RIOT"
> hiddenWord("test a b test")
""
> hiddenWord("test a b c test")
"abc"

答案 4 :(得分:0)

在您的终端/浏览器/控制台上试试这个:

var text = "FrankerZ R I O T FrankerZ";
var new_text = text.replace(/(\s\S(?=\s)){3,}/g, function(w){
    return(' ' + w.replace(/\s/g, ''));
});
console.log(new_text);

希望它能满足需求。

答案 5 :(得分:-1)

不是使用正则表达式,而是可以创建一个带字符串的函数,将字符串拆分为空格然后返回所有单个字母

    function findSingleLetters(string){
        var split = string.split(" ");
        var word= [];
        for(int i=0;i<split.length; i++){
            if(split[i].length==1){
               word.push(split[i]);
            }
        }
        return word.toString().replace(/,/g,"");  //join the word array and replace all the remaining commas(,)
    }

答案 6 :(得分:-1)

\b是一个零宽度断言,匹配字章程和非单词字符之间的差距。例如,/\b\w\s/R中的rZ R I匹配,但与Z不匹配:Z不遵循'分词',或者在function add(x) { return function(y) { return x + y; }; } 之间切换单词和非单词字符。尝试将它放在你的正则表达式的开头,以表明你不希望它在一个单词的中间开始匹配。