Sakari Niittymaa
Sakari Niittymaa

Reputation: 403

Update all numbers in string with JavaScript?

Main question is how I can update all numbers in string?

Examples where I want to update numbers in string:

So every "chunk" of numbers should be handled separately (e.g. 10 or 1 0 or 1px2, no matter if it's space or character between segment of numbers).

I got this working when I use spaces to split string, but it doesn't work in cases when string has no spaces rotate(7deg). Here is some small piece of "spaghetti code" example.

// Basic lerp
function lerp (min, max, amount) {
    return min + amount * (max - min);
}

// Lerp values in string
function lerpAllNumbers (a, b, amount) {
    var aNumbers = separateNumbers(a);
    var bNumbers = separateNumbers(b);
    var returnValue = null;
    if (aNumbers.length === bNumbers.length) {
        for (var i = 0; i < aNumbers.length; i++) {
            var searchString = aNumbers[i].value + aNumbers[i].extension;
            var newValue = lerp(aNumbers[i].value, bNumbers[i].value, amount).toFixed(3) + aNumbers[i].extension;
            returnValue = a.toString().replace(searchString, newValue);
        }
        return returnValue;
    }
}

// Separate numbers from string and create object with value and extension
function separateNumbers(text) {
    var splitter = text.toString().split(" ");
    var returnArray = [];
    splitter.forEach(function(item){
        var numberObj = {
            value: parseFloat(item),
            extension: item.replace(/^-?\d+((.|,)\d+)?/g, '')
        }
        returnArray.push(numberObj);
    });
    return returnArray;
}

Sorry if there is duplicates. I've found already useful post like this one: regex to split number from string

But none for this case where I need to update multiple numbers and put them back to string in right places after update.

Is there smarter/easier way to update all numbers in strings with JavaScript (Vanilla or jQuery)?

Upvotes: 2

Views: 525

Answers (2)

Sakari Niittymaa
Sakari Niittymaa

Reputation: 403

This answer based on @Wiktor Stribiżew answer and it replaces all values from string using other string values and calculate lerp values from those.

// Basic lerp function
function lerp (min, max, amount) {
    return min + amount * (max - min);
}

function lerpAllNumbers (a, b, amount) {

    a = 'rotate(-35.4deg 45.3deg)';
    b = 'rotate(100deg 200deg)';
    bArr = b.match(/-?\d*[,.]?\d+/g);

    console.log(
        a.replace(/-?\d*[,.]?\d+/g, function(m) {
            return utils.lerp(Number(m), bArr.shift(), amount).toFixed(3)
        })
    ); // rotate(99.946deg 199.938deg)
}

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626845

You need to use a String#replace with an anonymous callback method:

// Basic lerp
function lerp (min, max, amount) {
    return Number(min + amount * (max - min));
}

var s = "-ms-transform: rotate(7deg);";
var max = 15, amount = 2;
console.log(
  s.replace(/-?\d*[,.]?\d+/g, function(m) {
    return lerp(Number(m), max, amount).toFixed(3);
  })
);

The pattern is /-?\d*[,.]?\d+/g that matches multiple occurrences of an optional minus sign, 0+ digits followed with a , or . and then 1+ digits.

The function(m){} is the anonymous callback method passed to the String#replace method as a replacement argument where the value can be passed to other methods.

Upvotes: 1

Related Questions