Ramin Afshar
Ramin Afshar

Reputation: 1019

split string into array of n words per index

I have a string that I'd like to split in an array that has (for example) 3 words per index. What I'd also like it to do is if it encounters a new line character in that string that it will "skip" the 3 words limit and put that in a new index and start adding words in that new index until it reaches 3 again. example

var text = "this is some text that I'm typing here \n yes I really am"

var array = text.split(magic)

array == ["this is some", "text that I'm", "typing here", "yes I really", "am"]

I've tried looking into regular expressions, but so far I can't really make sense of the syntax that is used in regex.

I have written a way to complicated function that splits my string into lines of 3 by first splitting it into an array of separate words using .split(" "); and then using a loop to add add it per 3 into another array. But with that I can't take the new line character into account.

Upvotes: 4

Views: 2657

Answers (5)

alpha bravo
alpha bravo

Reputation: 7948

here one more way: use this pattern ((?:(?:\S+\s){3})|(?:.+)(?=\n|$))
Demo

Upvotes: 0

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

You can try with this pattern:

var result = text.match(/\b[\w']+(?:[^\w\n]+[\w']+){0,2}\b/g);

since the quantifier {0,2} is greedy by default, it will take a value less than 2 (N-1) only if a newline is found (since newlines are not allowed here: [^\w\n]+) or if you are a the end of the string.

Upvotes: 4

Rudie
Rudie

Reputation: 53781

Only if you know there are no words 'left', so the number of words is always a multiple of 3:

"this is some text that I'm typing here \n yes I really am".match(/\S+\s+\S+\s+\S+/g)
=> ["this is some", "text that I'm", "typing here \n yes", "I really am"]

but if you add a word:

"this is some text that I'm typing here \n yes I really am FOO".match(/\S+\s+\S+\s+\S+/g)

the result will be exactly the same, so "FOO" is missing.

Upvotes: 0

andmcgregor
andmcgregor

Reputation: 485

Try something like this:

words = "this is some text that I'm typing here \n yes I really am".split(" ");
result = [];
temp = "";

for (i = 0; i < words.length; i++) {
  if ((i + 1) % 3 == 0) {
    result.push(temp + words[i] + " ");
    temp = "";
  } else if (i == words.length - 1) {
    result.push(temp + words[i]);
  } else {
    temp += words[i] + " ";
  }
}

console.log(result);

Basically what this does is splits the string by words, then loops through each word. Every third word it gets to, it adds that along with what is stored in temp into the array, otherwise it adds the word to temp.

Upvotes: 1

gog
gog

Reputation: 11347

If you're interested in a regexp solution, it goes like this:

   text.match(/(\S+ \S+ \S+)|(\S+ \S+)(?= *\n|$)|\S+/g)
   // result ["this is some", "text that I'm", "typing here", "yes I really", "am"]

Explanation: match either three space separated words, or two words followed by spaces + newline, or just one word (a "word" being simply a sequence of non-spaces).

For any number of words, try this:

text.match(/((\S+ ){N-1}\S+)|(\S+( \S+)*)(?= *\n|$)|\S+/g)

(replace N-1 with a number).

Upvotes: 3

Related Questions