Question Details

No question body available.

Tags

javascript regex

Answers (2)

Accepted Answer Available
Accepted Answer
June 21, 2025 Score: 4 Rep: 164,875 Quality: Expert Completeness: 80%

You are repeating a capture group, which gives captures the value of the last iteration.

What you also can omit the the replacement first from comma's and spaces to a single space.

Then change the regex rgx to match a single char A-Za-z and capture following digits with a repeated comma and again digits in group 2.

Then split the group 2 value on a comma followed by optional white-space chars ,\s

([A-Za-z])(\d+(?:,\s\d+)+)

See the matches on regex 101

(if there can also be optional white-space chars before the comma, then you can change it to \s,\s)

As an example for your input (assuming that the Z is not matched because are no digits after it)

let path = `M4,24
    L4,23
    Q12,23,12, 9
    L14, 9
    C15, 3,25, 3,26,9
    L28,9
    Q28,23,36,23
    L36,24
    Z`

function parsePath(path) { let rgx = /([A-Za-z])(\d+(?:,\s\d+)+)/g return [...path.matchAll(rgx)] .map(x => [x[1], x[2] .split(/,\s/) ]) }

console.log(parsePath(path))

Or another way of writing it using Array.from and having the Z as undefined if there is no digit following using an optional capture group in the regex:

let path = `M4,24
    L4,23
    Q12,23,12, 9
    L14, 9
    C15, 3,25, 3,26,9
    L28,9
    Q28,23,36,23
    L36,24
    Z`

const rgx = /([A-Za-z])((?:\d+(?:,\s\d+)+)?)?/g;

const parsePath = path => Array.from( path.matchAll(rgx), x => [x[1], x[2] ? x[2].split(/,\s
/) : undefined] );

console.log(parsePath(path))

June 21, 2025 Score: 2 Rep: 22,975 Quality: Medium Completeness: 60%

Well I done this one...
it accept negative values, return numeric and don't care about aleatory spaces or other [carriage return]s separators.

const
  pathd =   // from some real apps
    document.querySelector('svg path').getAttribute('d') 
, path0 =   // from PO question
   `M4,24
    L4,23
    Q12,23,12, 9
    L14, 9
    C15, 3,25, 3,26,9
    L28,9
    Q28,23,36,23
    L36,24
    Z`
, path1 =  // mix space or comma separators !  20,20 0,0,1 50,30   
   `M 10,30
    A 20,20 0,0,1 50,30   
    A 20,20 0,0,1 90,30
    Q 90,60 50,90
    Q 10,60 10,30 z`
, path2 = // a bad one but the syntax is correct...
    `M-85.1487,-15.8513
    a 22.4171,22.4171 0 1 0 0,31.7026h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026Z
    Z`
, pathRegX  = /([a-z])(([-\d\s.,]+)?)/ig
, parsePath = path => 
    Array.from( path.matchAll(pathRegX),([,c,x]) =>
      [ c, x ? x.split(/[\s,]+/).map(Number) : []]  // space OR comma split
  );

console.log('path svg :') parsePath(path
d).forEach(x=>console.log(JSON.stringify(x))); console.log('\npath Data 0 :') parsePath(path0).forEach(x=>console.log(JSON.stringify(x))); console.log('\npath Data 1 :') parsePath(path1).forEach(x=>console.log(JSON.stringify(x))); console.log('\npath Data 2 :') parsePath(path_2).forEach(x=>console.log(JSON.stringify(x)));
svg {
  width      : 100px;
  background : lightblue;
  stroke     : darkblue;
  fill       : darkblue;
  }

.as-console-wrapper { max-height:100% !important; top:0; left:20% !important; width:80%; } .as-console-row { background-color: #feffb6; } .as-console-row::after { display:none !important; }