Find character characters except when surrounded by specific characters

Viewed 43

I have a string: "${styles.button} ${styles[color]} ${styles[size]} ${styles[_state]} ${iconOnly ? styles.iconOnly : ''}", and I'm trying to use regex to find all the spaces, except for spaces that are part of an interpolation string (${...}).

I'm willing to admit that regex might not be the right tool for this job, but I'm curious what I'm missing.

Essentially what I'm trying to do is replace the spaces with a newline character.

3 Answers

Assuming you have only have ${...} patterns separated by space as per your example you can apply this regex:

var str = "${styles.button} ${styles[color]} ${styles[size]} ${styles[_state]} ${iconOnly ? styles.iconOnly : ''}"
var re = /(\}) +(\$\{)/g;
var result = str.replace(re, "$1\n$2");
console.log('result: ' + result);

Result:

result: ${styles.button}
${styles[color]}
${styles[size]}
${styles[_state]}
${iconOnly ? styles.iconOnly : ''}

You can split the string in interpolation string and non-interpolation string sequences and then only modify the odd sequences (the resulting array always starts with a non-interpolation string, don't worry about that). This has to be done, because regular expressions are limited in the states they can remember (for more about that study CS). A solution would be:

var string = "${styles.button} ${styles[color]} ${styles[size]} ${styles[_state]} ${iconOnly ? styles.iconOnly : ''}";
var result = string
// split in non-interpolation string and interpolation string sequences
.split(/(\${[^}]*})/g)
// modify the sequences with odd indices ( non-interpolation)
.map((part, i) => (i % 2 ? part : part.replace(/ +/g, '')))
// concatenate the strings
.join('');

console.log(result);

But also mind the comment by ggorlen on your question:

Looks like you're trying to use regex to parse arbitrary JS template strings. That isn't an easy task in the general case and regex is probably the wrong tool for the job--it's likely an xy problem. Can you provide more context (why do you need to parse JS template strings in the first place?) and show an attempt? Thanks.

I tested with a simple find ' \$' (without quotes), replace with '\n$' (without quotes) - in sublime text regex search, works well

Related