skip to Main Content

I need to manipulate drawing of a SVG, so I have attribute "d" values like this:

d = "M561.5402,268.917 C635.622,268.917 304.476,565.985 379.298,565.985"

What I want is to "purify" all the values (to strip the chars from them), to calculate them (for the sake of simplicity, let’s say to add 100 to each value), to deconstruct the string, calculate the values inside and then concatenate it all back together so the final result is something like this:

d = "M661.5402,368.917 C735.622,368.917 404.476,665.985 479.298,665.985"

Have in mind that:

  • some values can start with a character
  • values are delimited by comma
  • some values within comma delimiter can be delimited by space
  • values are decimal

This is my try:

    let arr1 = d.split(',');
    arr1 = arr1.map(element => {
      let arr2 = element.split(' ');
      if (arr2.length > 1) {
        arr2 = arr2.map(el => {
          let startsWithChar = el.match(/D+/);
          if (startsWithChar) {
            el = el.replace(/D/g,'');
          }
          el = parseFloat(el) + 100;
          if (startsWithChar) {
            el = startsWithChar[0] + el;
          }
        })
      }
      else {
        let startsWithChar = element.match(/D+/);
        if (startsWithChar) {
          element = element.replace(/D/g,'');
        }
        element = parseFloat(element) + 100;
        if (startsWithChar) {
          element = startsWithChar[0] + element;
        }
      }          
    });
    d = arr1.join(',');

I tried with regex replace(/D/g,'') but then it strips the decimal dot from the value also, so I think my solution is full of holes.

Maybe another solution would be to somehow modify directly each of path values/commands, I’m opened to that solution also, but I don’t know how.

2

Answers


  1. const s = 'M561.5402,268.917 C635.622,268.917 304.476,565.985 379.298,565.985'
    
    console.log(s.replaceAll(/[d.]+/g, m=>+m+100))
    Login or Signup to reply.
  2. You might use a pattern to match the format in the string with 2 capture groups.

    ([ ,]?b[A-Z]?)(d+.d+)b
    

    The pattern matches:

    • ( Capture group 1
      • [ ,]?b[A-Z]? Match an optional space or comma, a word boundary and an optional uppercase char A-Z
    • ) Close group 1
    • ( Capture group 2
      • d+.d+ Match 1+ digits, a dot and 1+ digits
    • ) Close group 1
    • b A word boundary to prevent a partial word match

    Regex demo

    First capture the optional delimiter followed by an optional uppercase char in group 1, and the decimal number in group 2.

    Then add 100 to the decimal value and join back the 2 group values.

    const d = "M561.5402,268.917 C635.622,268.917 304.476,565.985 379.298,565.985";
    const regex = /([ ,]?b[A-Z]?)(d+.d+)b/g;
    const res = Array.from(
      d.matchAll(regex), m => m[1] + (+m[2] + 100)
    ).join('');
    
    console.log(res);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search