You're going to have trouble solving this entire problem with regular expressions alone.
That is to say, there is no regular expression that will do all of the following:
- select nothing you're not interested in
- capture everything you're interested in
- capture a variable number of matches
The last requirement -- a variable number of captures -- is the big one. StackOverflow user Tomalak described the situation quite well:
Groups are defined thorugh parentheses. Your match result will contain as many groups as there are parentheses pairs in your regex (except modified parentheses like (?:...) which will not count towards match groups). Want two separate group matches in your match result? Define two separate groups in your regex.
If a group can match multiple times, the group's value will be whatever it matched last. All previous match occurrences for that group will be overridden by its last match.
You can still let a regular expression do much of the work, though, for example using the \b
boundary-of-word anchor. This is much like what you were describing as "a space before and after it" but is closer to what you want because it doesn't match (or even require) the space itself.
> "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"]
You wanted quantification, and of course this regex contains no quantifiers:
> "test a b test".match(/\b\w\b/g)
["a", "b"]
But you can do this outside of the regular expression:
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"