'Split string of possibly adjacent elements of unknown length by type in JS

Given a string (actually a svg path) such as:

"M72 0v754h405v-86h-311v-211h302v-86h-302v-285h311v-86h-405z"

I want to obtain an array where each element is either a letter, either a full positive or negative number, like this:

[M, 72, 0, v, 754, h, 405, v, -86, h, -311, v, -211, h, 302, v, -86, h, -302, v, -285, h, 311, v, -86, h, -405, z]

I thought about using split() with a regex, but I believe that would not work with adjacent elements such as "M72" as there is nothing between them that I can target for the split.

Is the only solution a custom char per char loop that finds the beginning and end of each type of element I am looking for, possibly with regex?



Solution 1:[1]

You could match either a letter or a number with an optional minus sign.

var string = "M72 0v754h405v-86h-311v-211h302v-86h-302v-285h311v-86h-405zx-12.4y0.001",
    parts = string.match(/[a-z]|-?\d+\.?\d*/gi);
    
console.log(parts);

Solution 2:[2]

You're on the right track with regex, but you can take advantage of the fact that with split, any capturing groups in the pattern will be returned along with the strings on either side of the match.

A pattern like /\s*([-+]?\d+)\s*/g will select any numbers and split the string around those numbers. The result may contain empty strings, but those can be removed with filter pretty easily.

var input = "M72 0v754h405v-86h-311v-211h302v-86h-302v-285h311v-86h-405z";
var result = input.split(/\s*([-+]?\d+)\s*/g).filter(String);
console.log(result);

Solution 3:[3]

You could use SVG.js to achieve this: https://svgjs.dev/docs/2.7/classes/#svg-patharray

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 p.s.w.g
Solution 3 wout