0

I have an array of strings that look like the following:

const stringArray = [
    'string1[1] string2[2] string3[3] [4 5]',
    'string6[6] string7[7] string8[8] [9 10]'
];

I want to be able to separate each string into four rows (in this case, because there are 4 columns). So the array would end up like:

const splittedArray = [
    [
        'string1[1]',
        'string2[2]',
        'string3[3]',
        '[4 5]'
    ],
    [
        'string6[6]',
        'string7[7]',
        'string8[8]',
        '[9 10]'
    ]
]

I've been searching and trying regex even though I am not a fan of it as it is unreadable, but it does not seem to be working.

Whenever I try /(?=\])\s/g it does not separate the string, whenever I try /(?=\])\s*/ it separates the string and keeps both the ] and the whitespace, but does so in the next line (and well, keeps the whitespace).

I can't seem to find a way to do what I want, but perhaps I'm just miss understanding something. Perhaps there is a simpler way to do this. Splitting after the ] without needing to check for a space would be ideal but I would still have the problem of keeping the bracket and not splitting an extra time on that last ] hence why I'm trying this solution.

Here is a little code snipper with what I have and what it returns:

const stringArray = [
  'string1[1] string2[2] string3[3] [4 5]',
  'string6[6] string7[7] string8[8] [9 10]'
];

const splittedStringArray = stringArray.map(string => string.split(/(?=\])\s/g));

console.log(splittedStringArray);

const anotherSplittedStringArray = stringArray.map(string => string.split(/(?=\])\s*/g));

console.log(anotherSplittedStringArray);

const splittedByBrackets = stringArray.map(string => string.split(/(?=\])/));

// The same as the previous one
console.log(splittedByBrackets);

For my case, the answer was: /\w*\[.*?\]/g (with match instead of split) by Thomas. From what I understood:

The \w* matches any word (0 or more times)

The \[ matches the [ after a word (or no word, above condition)

The .*? matches any character excluding line breaks (0 or more times) lazyly, I believe the ? is to tell to stop matching on the first character(s) otherwise it would search the whole string.

The \] matches the ] after what is after the other bracket (which is the above condition).

The /g flag makes it so it searched for more than one occurrence.

  • 1
    Possible dupes: [parsings strings: extracting words and phrases](https://stackoverflow.com/questions/64904/parsings-strings-extracting-words-and-phrases-javascript), [Split string into words with whitespace unless in between a pair of double quotation marks](https://stackoverflow.com/questions/18703669/split-string-into-words-with-whitespace-unless-in-between-a-pair-of-double-quota) – Andreas Jun 02 '20 at 11:04

3 Answers3

1

You could take a positive lookbehind for a closing bracket.

const stringArray = [
  'string1[1] string2[2] string3[3] [4 5]',
  'string6[6] string7[7] string8[8] [9 10]'
];

const splittedStringArray = stringArray.map(string => string.split(/(?<=\])\s/g));

console.log(splittedStringArray);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thank you for your comment but seems like that is a positive lookbehind according to https://regexr.com/ and that it does not have support for quite a bit of browsers (as it warns you there, and can check at https://caniuse.com/#feat=js-regexp-lookbehind). – Gustavo Vieira Jun 02 '20 at 11:09
0

Instead of splitting by what you don't want, you could also match the parts that you want.

const stringArray = [
  'string1[1] string2[2] string3[3] [4 5]',
  'string6[6] string7[7] string8[8] [9 10]'
];

const splittedStringArray = stringArray.map(string => string.match(/\w*\[.*?\]/g));

console.log(splittedStringArray);
Thomas
  • 11,958
  • 1
  • 14
  • 23
  • I found this to be the best answer. It works for my case and it doesn't care on how many spaces there are between words. Thank you :) – Gustavo Vieira Jun 02 '20 at 11:35
-1

Using Negative Lookahead

\s(?![^\[]*\])

Regex Demo

const stringArray = [
  'string1[1] string2[2] string3[3] [4 5]',
  'string6[6] string7[7] string8[8] [9 10]'
];

const splittedStringArray = stringArray.map(string => string.split(/\s(?![^\[]*\])/g));

console.log(splittedStringArray);
User863
  • 19,346
  • 2
  • 17
  • 41
  • This worked for my use case. Still need to understand a little bit better what it does exactly and am trying to improve it for more use cases. Thank you for your answer! – Gustavo Vieira Jun 02 '20 at 11:29
  • In precise, it matches all spaces not between `[` and `]`. Check explanation in the demo link. – User863 Jun 02 '20 at 11:32