Is there a library for replacing using functions as argument
when I call this function
"foo[10]bar[20]baz".replacef(/\[([0-9]*)\]/g, function(a) {
return '[' + (ParseInt(a)*10) + ']';
});
it should return
"foo[20]bar[30]baz";
and when I call with this
"foo[10;5]bar[15;5]baz".replacef(/\[([0-9]*);([0-9]*)\]/g, function(a, b) {
return '_' + (ParseInt(a)+ParseInt(b)) + '_';
});
it should return
"foo_15_bar_20_baz"
Is there existing Cross-Browser library that have function like this or similar in JavaScript?
That's how the "replace()" function already works. If the second parameter is a function, it's passed a list of arguments that are pretty much the same as the array returned from the RegExp "exec()" function. The function returns what it wants the matched region to be replaced with.
The first argument to the called function is the whole matched string. The second and subsequent arguments are the captured groups from the regex (like your second example). Your second example, however, would need a function with one more parameter to hold the entire matched string.
Example:
var s = "hello world".replace(/(\w+)\s*(\w+)/, function(wholeMatch, firstWord, secondWord) {
return "first: " + firstWord + " second: " + secondWord;
});
alert(s); // "first: hello second: world"
As far as I know you can readily do something like this in javascript :
"foo[10]bar[20]baz".replace(/\[([0-9]+)\]/g, function() {
return '[' + (parseInt(arguments[1])*10) + ']';
});
This is afaik cross browser (notice that parseInt got no leading uppercase p), arguments contains the match, index 0 is the whole thing, 1 and so on are the captured groups.
Related
I made a function to break a string to break it into parts.
I read on MDN that by putting regex in parentheses I could refer it later by using $1 but for some reason my code is not working.
I want this function to return 'url this' but it is return '$ 1his'.
Please Help!
const someFunction = str => {
return str.replace(/([A-Z]+)/g,('$1'.slice(0,-1).toLowerCase() + ' ' + '$1'.slice(-1).toLowerCase()));
}
console.log(someFunction('URLThis'))
You can pass function in the second parameter to string#replace.
const someFunction = str => {
return str.replace(/[A-Z]+/g, (match) => {
return match.slice(0,-1).toLowerCase() + ' ' + match.slice(-1).toLowerCase();
});
}
console.log(someFunction('URLThis'))
You are going to want to use a function as the second parameter for manipulating the result of the replacement. From MDN String.prototype.replace():
Because we want to further transform the result of the match before
the final substitution is made, we must use a function. This forces
the evaluation of the match prior to the toLowerCase() method. If we
had tried to do this using the match without a function, the
toLowerCase() would have no effect.
This is because '$&'.toLowerCase() would be evaluated first as a
string literal (resulting in the same '$&') before using the
characters as a pattern.
Could you please explain how this piece of code works?
String.prototype.replaceAt = function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
};
function titleCase(str) {
var newTitle = str.split(' ');
var updatedTitle = [];
for (var st in newTitle) {
updatedTitle[st] = newTitle[st].toLowerCase().replaceAt(0, newTitle[st].charAt(0).toUpperCase());
}
return updatedTitle.join(' ');
}
titleCase("I'm a little tea pot");
Specifically, what exactly is passed onto to replaceAt (I get that it's passed an index, and a character that's converted to lowercase), but what does replaceAt DO with it?
So, in the first iteration of the loop, it's passed replaceAt(0, i) right? Then what does replaceAt do with this? I just don't get this line:
this.substr(0, index) + character + this.substr(index+character.length)
I've already read this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr. I'm here because I don't understand that return statement and what exactly it's doing.
Suppose you execute "thisisatest".replaceAt(3, "h").
Then...
this.substr(0, index) returns "thi" : ie the first 3 characters of "thisisatest"
character returns "h"
this.substr(index+character.length) returns "isatest" : ie all characters of "thisisatest", starting at position 4
So, when you combine this, you get "thihisatest"
Lets imagine this easy case:
"0123456789". replaceAt(2/*index*/,"000"/*character*/)
Then this happens:
this.substr(0, index/*2*/)//"01"
+ character //"000"
+ this.substr(index/*2*/+character.length/*3*/)//"56789"
Output:
0100056789
The replaceAt function simply takes the index of a character (0 in this case) and replaces it with another character (in this case the uppercase version of the original character. This specific function is just Title Casing a word by replacing the first character with the same character in uppercase.
The line that your questioning, takes a substring of the word before the character at the specificied index this.substr(0,index) since substr is non-inclusive of the last index, appends the specified character + character, and appends a substr of the rest of the word + this.substr(index+character.length)
Example 'testing'.replaceAt(0,testing.charAt(0).toUpperCase());
= '' + 'T' + 'esting' = Testing;
this.substr is a function that operates on a string and returns a 'sub string' of the string. See a tutorial here: https://www.w3schools.com/jsref/jsref_substr.asp
So what replaceAt is doing is operating on a string and replacing the character at the target index, index, with the new substring, character. Indeed the passed character does not have to be only one character but could be multiple, like abcd. It is rather poorly named.
For more detail, using substr(), it is taking the first part of the string from index 0 to index, adding the 'character/string' passed to the function, and then taking the rest of the string from index index+character.length onwards. Note that substr has an optional parameter which is used in the first call (this.substr(0,index)).
function expand(element) {
var target = document.getElementById(element);
var h = target.offsetHeight;
var sh = target.scrollHeight;
var loopTimer = setTimeout('expand(\'' + element + '\')', 10);
if (h < sh) {
h += 1;
} else {
clearTimeout(loopTimer);
alert("伸縮完成");
}
target.style.height = h + "px"
}
\' is an escape character for ', so what this is doing is building a string that can be consumed as a function, which contains a parameter, which is wrapped in single quotes...
'expand(\''
The above portion "opens" the string, applies expand( as a literal, then an escaped ', followed by one more ' to close that portion of the string. So, the return on that is:
expand('
Next, they concatenate the value of element variable:
'expand(\'' + element
The string now contains:
expand('elementVariableValue
Next up is to open another literal string, add in another single quote (escaped), followed by the closing parenthese:
'\')'
this is evaluated to:
')
put it all together and you get:
expand('elementVariableValue')
(which is finally interpreted as a function for the timeout).
Now, with JavaScript, you can use both " and ' for string delimiters, so much easier might have been:
setTimeout("expand('" + element + "')", 10);
Code in your example is a recursive call. It's a timer and the callback is expand(element). Understand this, you can easy understand that var loopTimer = setTimeout('expand(\'' + element + '\')', 10); means another call to expand(element). However, function expand need a string parameter, so \'' + element + '\' it is. Finally, if element here equals to scaleid, we finally get expand('scaleid'), it is obviously another call to expand(). Cause it is in string, so \' is needed to escape it.
In Javascript you can pass as the first parameter of the function a string, this string is evaluated as if you use eval(). That code is like if you call the function expand("something") every 10 milliseconds.
I'm trying to figure out a way to use the replace() function to find strings such as "23-34". So far Iv'e been using the following code for similar purposes, and Id'e like to keep using the function replace (nevermind that it doesn't do anything yet).
function Work() {
function PleaseWork(match) {
var x = +match + 408;
x = ' ' + x;
return x;
}
document.getElementById("InputText").value = document.getElementById("InputText").value.replace(/\s+\d+/g, PleaseWork);
}
Iv'e tried to replace the expression /\s+\d+/g with /\d+\-\d+/g. But unfortunately that won't run or won't result in taking away the instances I need it to take.
Any advises?
I hope this is a valid answer:
function Work() {
function PleaseWork(match) {
// this is your array: match.split('-')
return '[' + match.split('-') + ']';
}
document.getElementById("InputText").value = document.getElementById("InputText").value.replace(/\d+-\d+|\d+/g, PleaseWork);
}
You want match() not replace(), match returns an array with the matches.
Also, beware of the minus key vs dash key. They are different values on the ASCII table.
I have a regular expression, say /url.com\/([A-Za-z]+)\.html/, and I would like to replace it with new string $1: f($1), that is, with a constant string with two interpolations, the captured string and a function of the captured string.
What's the best way to do this in JavaScript? 'Best' here means some combination of (1) least error-prone, (2) most efficient in terms of space and speed, and (3) most idiomatically appropriate for JavaScript, with a particular emphasis on #3.
The replace method can take a function as the replacement parameter.
For example:
str.replace(/regex/, function(match, group1, group2, index, original) {
return "new string " + group1 + ": " + f(group1);
});
When using String.replace, you can supply a callback function as the replacement parameter instead of a string and create your own, very custom return value.
'foo'.replace(/bar/, function (str, p1, p2) {
return /* some custom string */;
});
.replace() takes a function for the replace, like this:
var newStr = string.replace(/url.com\/([A-Za-z]+)\.html/, function(all, match) {
return match + " something";
});
You can transform the result however you want, just return whatever you want the match to be in that callback. You can test it out here.