I'm new to javascript so apologies if I've missed something simple. I'm working on a script to take a string from one cell in Sheets, add VAT at 5% to any applicable numbers and output the amended string in a new cell. I'm happy with the regex capturing the numbers I need, but getting the amended string correct is proving tricky.
So far the script looks like this:
function strReplace() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var str = sheet.getRange(4,2).getValue(); // A cell with a string like this: "ID: 10101010101010 | Price 1: £4.54 | Price 2: £2.87"
var regex = /\d{1,8}(?:\.\d{1,8})/g // Regex to ignore numbers greater than 8 digits, including decimals
var newStr = str.match(regex);
for (var x = 0; x < newStr.length; x++) {
var newRates = newStr[x]*1.05;
var output = str.replace(newStr, newRates)
sheet.getRange(4,3).setValue(output);
}
}
I've tried a bunch of variations but with no success. I feel there is an easier way to achieve what I'm looking for from what I already have. Any recommendations would be much appreciated.
Thanks!
To do this kind of thing, you use the function callback version of replace:
var str = "ID: 10101010101010 | Price 1: £4.54 | Price 2: £2.87";
var regex = /\d{1,8}(?:\.\d{1,8})/g; // Regex to ignore numbers greater than 8 digits, including decimals
var output = str.replace(regex, function(match) {
return 1.05 * match;
});
console.log(output);
You might choose to use parseFloat(match) rather than just using match, which relies on * coercing the string to number.
And you might consider .toFixed(2) on the result to round and format to two places (depending on whether you want to round the way it rounds). For instance:
var str = "ID: 10101010101010 | Price 1: £4.54 | Price 2: £2.87";
var regex = /\d{1,8}(?:\.\d{1,8})/g; // Regex to ignore numbers greater than 8 digits, including decimals
var output = str.replace(regex, function(match) {
return (1.05 * match).toFixed(2);
});
console.log(output);
basically your solution is very close, you just needed tot assign the str.replace, use the newStr[x] and also wait to end the for to assign it into the cell.
check the sample below.
function strReplace() {
let str = "ID: 10101010101010 | Price 1: £4.54 | Price 2: £2.87";
var regex = /\d{1,8}(?:\.\d{1,8})/g
var newStr = str.match(regex);
for (var x = 0; x < newStr.length; x++) {
var newRates = parseFloat(newStr[x]) * 1.05;
str = str.replace(newStr[x], newRates)
}
return str;
}
var replaced = strReplace();
console.log(replaced)
Related
I'm working to update this function which currently takes the content and replaces any instance of the target with the substitute.
var content = textArea.value; //should be in string form
var target = targetTextArea.value;
var substitute = substituteTextArea.value;
var expression = new RegExp(target, "g"); //In order to do a global replace(replace more than once) we have to use a regex
content = content.replace(expression, substitute);
textArea.value = content.split(",");
This code somewhat works... given the input "12,34,23,13,22,1,17" and told to replace "1" with "99" the output would be "992,34,23,993,22,99,997" when it should be "12,34,23,13,22,99,17". The replace should only be performed when the substitute is equal to the number, not a substring of the number.
I dont understand the comment about the regex needed to do a global replace, I'm not sure if that's a clue?
It's also worth mentioning that I'm dealing with a string separated by either commas or spaces.
Thanks!
You could do this if regex is not a requirement
var str = "12,34,23,13,22,1,17";
var strArray = str.split(",");
for(var item in strArray)
{
if(strArray[item] === "1")
{
strArray[item] = "99"
}
}
var finalStr = strArray.join()
finalStr will be "12,34,23,13,22,99,17"
Try with this
var string1 = "12,34,23,13,22,1,17";
var pattern = /1[^\d]/g;
// or pattern = new RegExp(target+'[^\\d]', 'g');
var value = substitute+",";//Replace comma with space if u uses space in between
string1 = string1.replace(pattern, value);
console.log(string1);
Try this
target = target.replace(/,1,/g, ',99,');
Documentation
EDIT: When you say: "a string separated by either commas or spaces"
Do you mean either a string with all commas, or a string with all spaces?
Or do you have 1 string with both commas and spaces?
My answer has no regex, nothing fancy ...
But it looks like you haven't got an answer that works yet
<div id="log"></div>
<script>
var myString = "12,34,23,13,22,1,17";
var myString2 = "12 34 23 13 22 1 17";
document.getElementById('log').innerHTML += '<br/>with commas: ' + replaceItem(myString, 1, 99);
document.getElementById('log').innerHTML += '<br/>with spaces: ' + replaceItem(myString2, 1, 99);
function replaceItem(string, needle, replace_by) {
var deliminator = ',';
// split the string into an array of items
var items = string.split(',');
// >> I'm dealing with a string separated by either commas or spaces
// so if split had no effect (no commas found), we try again with spaces
if(! (items.length > 1)) {
deliminator = ' ';
items = string.split(' ');
}
for(var i=0; i<items.length; i++) {
if(items[i] == needle) {
items[i] = replace_by;
}
}
return items.join(deliminator);
}
</script>
I have to replace the digits in the first (n-4) characters of credit card with '*'.
I am using following three lines of code.
var cardnumber = '1A2C3GF4DS84Ff';
last4digits = cardNumber.substring(cardNumber.length-4);
prevdigits = cardNumber.substring(0, cardNumber.length-4).replace(/[0-9]/g,'*');
$cache.cardNumber.val( prevdigits + last4digits);
Just wondering can I do it in just one line of code by using regex.
Use a look-ahead to ensure that there are at least four remaining characters after the digit. In other words, digits within the last four characters will not match:
var regexp = /\d(?=....)/g;
> cardnumber.match(regexp)
< ["1", "2", "3", "4"]
To replace with asterisks:
> cardnumber.replace(regexp, '*')
< "*A*C*GF*DS84Ff"
Information on look-aheads is here.
From here I got this code.
var text = '1ab2cb3cd4ab5cb6cd7';
var matches = text.match(/(\d)/g);
for (i=0; i<matches.length; i++) {
alert(matches[i]);
}
Actually, they wanted to extract digits too. I don't need to change the regex.
You can limit it to 5 by making the loop start with:
for (i=0; i<matches.length && i < 5; i++){
Just use (\d) and check it programmatically afterwards.
var y= x.replace(/\D/g, '').substring(0, 5);
The .replace() function can use a function as the replacement, and it will be called for each match. It can keep a counter and return something different based on the counter.
var str = '1A2C3GF4DS84Ff';
var digits = 0;
var newstr = str.replace(/\d/g, function(match) {
if (digits++ < 4) {
return '*';
} else {
return match;
}
});
document.write(newstr);
looks like following one does the job You need:
var text= '1A2B3C4D5E6F',
n = 5;
text = text.replace(/\d/g, function ($1){
return n-- ?'*' : $1
});
I have a variable (in this example var str = "I!%1$s-I!%2$s TTL!%3$s";), in which I want to replace the % with elements from an array (var regex = ['aaa', 'bbb', 'ccc'];).
I google around a bit and found this solution, but I'm having trouble implementing it. My problem is that I want to replace a single character with multiple characters, and then continue the string, but this just overwrites the characters. I actually have no idea why.
Any help is appreciated, my code below
String.prototype.replaceAt = function(index, character) {
return this.substr(0, index) + character + this.substr(index + character.length);
}
var str = "I!%1$s-I!%2$s TTL!%3$s";
var regex = ['replace', 'replace', 'replace'];
//find position of %
var find = /%/gi,
result, pos = [];
while ((result = find.exec(str))) {
pos.push(result.index);
}
//replace % with regex elements
for (x = 0; x < pos.length; x++) {
str = str.replaceAt(pos[x], regex[x]);
}
document.write(str);
Use replacement function, like this
var str = "I!%1$s-I!%2$s TTL!%3$s";
var regex = ['[123]', '[456]', '[789]'];
console.log(str.replace(/%(\d+)/g, function(match, group1) {
return regex[parseInt(group1) - 1] + group1;
}));
// I![123]1$s-I![456]2$s TTL![789]3$s
The RegEx /%(\d+)/g matches anything of the pattern % followed by one or more digits. And it captures the digits as a group. Then the exact match and the group is passed to the function to get the actual replacement. In the function, you convert the group to a number with parseInt and return the respective value from the regex array.
How can a sentence be truncated to a certain number of words (NB. not letters)?
I thought to use split(" "), but then how do I count out words?
For example:
Javascript word count cut off => Javascript word count
Want better search results? See our search tips! => Want better search
You can use split [MDN] and join [MDN].
"Want better search results? See our search tips".split(" ").splice(0,3).join(" ")
Here's a "read more" function I wrote for my Meteor app. It accepts a maxWords parameter and strips html tags using jquery's text() method.
Hope it helps!
function readMore(string, maxWords) {
var strippedString = $("<p>" + string + "</p>").text().trim();
var array = strippedString.split(" ");
var wordCount = array.length;
var string = array.splice(0, maxWords).join(" ");
if(wordCount > maxWords) {
string += "...";
}
return string ;
}
Pure solution with ES6, defaults to 10 words
const truncate = (str, max = 10) => {
const array = str.trim().split(' ');
const ellipsis = array.length > max ? '...' : '';
return array.slice(0, max).join(' ') + ellipsis;
};
Splitting works, as you have described it. If you use a RegExp, however, you don't have to split the whole string:
var str = "Lions and tigers and bears";
var exp = /[A-Z|a-z]+/g;
var a = exp.exec(str); // Lions
var b = exp.exec(str); // and
var c = exp.exec(str); // tigers
quick question, I have some integrate variable in javascript, say: 123456, or 123456789, it can be any valid number. Now, I would like to convert the number to a string like "123,456" or "123,456,789". Does anyone have a good algorithm for this? Of course, it should work for any numbers. For example: for 2000 ---> 2,000; 123456--->123,456
Give this a shot.
var num = 12345678;
var str = num + ""; // cast to string
var out = [];
for (var i = str.length - 3; i > 0; i -= 3) {
out.unshift(str.substr(i, 3));
}
out.unshift(str.substr(0, 3 + i));
out = out.join(','); // "12,345,678"
in addition to the other excellent solution
var n = 999999
var s = n.toLocaleString()