Home > Mobile >  Calculating mixed numbers and chars and concatinating it back again in JS/jQuery
Calculating mixed numbers and chars and concatinating it back again in JS/jQuery

Time:12-03

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.

CodePudding user response:

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))

CodePudding user response:

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);

  • Related