Reputation: 403
Main question is how I can update all numbers in string?
Examples where I want to update numbers in string:
-ms-transform: rotate(7deg);
margin: 10px 20px 30px 40px;
Value10isMoreThan5
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
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
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