I am trying to replace matches of text between dollar signs.
So the text $match$ inside Some text and $some text that matches$. should be replaced.
I have tried
text.replace(/\$.*?\$/g, function (match) {
return '_' + match + '_';
}
This works. The problem is that I want to do evaluate the match inside this function, but sometimes the evaluation didn't work, and in these cases I just want to return the original match. So it is something like
text.replace(/\$.*?\$/g, function (match) {
try {
return evaluate(match);
} catch (e) {
return match;
}
}
But with my current regex, the match contains the dollar signs from the original text. I want it to omit the dollar signs, but if the evaluation fails, then I want the original dollar signs back.
What I could do is
text.replace(/\$.*?\$/g, function (match) {
try {
return evaluate(match.replace(/\$/g, ''));
} catch (e) {
return match;
}
}
but isn't it possible in a more elegant way?
Something like this might do:
const evaluate = function(str) {
if (str && str.startsWith("t")) {return str.toUpperCase();}
throw "Gotta hava a 'T'";
};
"ab$test$cd $something$ that is $tricky$.".replace(/\$([^$]*)\$/g;, function(str, match) {
try {
return evaluate(match);
} catch(e) {
return str;
}
}); //=> "abTESTcd $something$ that is TRICKY."
But I agree with the comment that you might be better returning a different signal (undefined? null?) from evaluate rather than throwing for this case. And then the function body could simply be something like:
return evaluate(match) || str;
The point is the capturing group in the regex: /\$([^$]*)\$/g;, which becomes a parameter to the replacement function.
Related
I need to modify this function to work properly. It is supposed to restrict everything but the alphabet, spaces, and apostrophes. Currently it is still restricting apostrophes. I'm assuming the pattern ' \ _ ' is referring to ALL special characters. How would I insert an exception in to this function?
function NameNotNA (s) {
var pattern;
if (s.toUpperCase().indexOf('N/A') != -1){
//console.warn('failed in n/a');
return false;
}
// Eliminate possibility of digits
pattern = /\d/;
if (s.match(pattern) != null) {
//console.warn('failed in \d');
return false;
}
pattern = /\_/;
if (s.match(pattern) != null) {
//console.warn('failed in \_');
return false;
}
s = s.replace(/ /g, '');
if (s.match(/\W/) != null) {
return false;
}
return true;
}
function nameNotNA (s) {
return s.replace(/[^\w\s']/g, '');
}
For regex, I like using this tool to understand exactly what's happening. Also, it's good to keep your function names lowerCamelCase unless it's a Class.
This is a solution to a toy problem in Javascript. The job was to find a Palindrome(word that you can read the same back and forth, like "radar", "rotor") in a string with words separated by spaces or return an empty string if no word fits the requirement. i understand everything but i don´t know how they use the reduce method to find the word, especially the syntax " ? word : prevWord"
Could somebody explain??
function reverseString(str) {
return str.split('').reverse().join('');
}
function isPalindrome(str) {
return str === reverseString(str);
}
function getWords(str) {
return str.split(' ');
}
function findPalindrome(str) {
var words = getWords(str);
return words.reduce(function(prevWord, word) {
return isPalindrome(word) ? word : prevWord;
}, '');
}
As you can see if i use the last function
findPalindrome("this is a very good rotor");
It will return
"rotor"
I have a regular expression and I'm wondering if I can use all matches as an argument for a function. For example, let's say that I have a data set
Hello heelo hhhheEEeloo eelloooo
and a regular expression
/[Hh]{1,}[Ee]{1,}[Ll]{1,}[Oo]{1,}/
which would match
Hello heelo hhhheEEeloo
how can I get a javascript function to take in each match as an argument, for example
function isHello(arg) {
if (arg == 'Hello') { return 1 }
else { return 0}
}
Use .replace with a callback
"Hello heelo hhhheEEeloo eelloooo".replace(/[Hh]{1,}[Ee]{1,}[Ll]{1,}[Oo]{1,}/g,function(match){
//Your function code here
return match;
})
Or a more trivial example:
var count=0;
"aaaaaaa".replace(/a/g,function(match){
console.log("I matched another 'a'",count++);
// just to not replace anything, technically this doesn't matter
//since it doesn't operate on the actual string
return match;
});
Fiddle
var string = "Hello heelo hhhheEEeloo eelloooo",
regex = /[Hh]{1,}[Ee]{1,}[Ll]{1,}[Oo]{1,}/g,
fn = function(arg){
if (arg == 'Hello')
return 1;
return 0
};
string.match(regex).forEach(fn);
Notice the g flag added to the regex to match in order to give the desired match.
Here is an example using match():
var s = "Hello heelo hhhheEEeloo eelloooo";
s.match(/[Hh]{1,}[Ee]{1,}[Ll]{1,}[Oo]{1,}/g).forEach(function(entry) {
// your function code here, the following is just an example
if (entry === "Hello")
console.log("Found Hello!");
else
console.log(entry + " is not Hello");
return;
});
Example: http://jsfiddle.net/wTMuF/
I've a regex that will only match one character of the strings. I want to test the lentgh of its containing string and if it was greater than 4 then make the replacement. For example, the regex is /\d/. I want to use the functional form of replace to match 12345 but not 1234.
Something like:
text.replace(regex, function(match) {
if (STRING.length > 4)
return replacement
else
return match;
});
Note:
/\d/ is just an example. I didn't mention the real regex to focus on my real question, illustrated above.
Or if you want to do it that way:
function replaceWithMinLength (str, minLength) {
str.replace(/\w+/, function(match) {
if (match.length > minLength) {
return match;
} else {
return str;
}
});
}
You're putting the horse before the cart. You would be better off:
if(string.length > 4) {
string.replace('needle','replacement');
}
So by “containing string”, you mean like the same sequence of digits? Match them all at once:
text.replace(/\d{5,}/g, function(string) {
return string.replace(/\d/g, function(match) {
return replacement;
});
});
For example. The \d{5,} can easily be adapted to any type of string-thing.
I am writing a function which takes string as an argument. Then if the string begins with capital letter then return true otherwise return false. But my current function only works for one word string which I want it to work for both one word and a whole sentence. How can I improve my code to achieve this? Secondly, it should not work when numbers are passed inside sentence. How can I do this?
Here is my code
function takeString (str) {
var regex = /^[A-Za-z]+$/;
if (str.match(regex)) {
if (str.charAt(0) === str.toUpperCase().charAt(0)) {
alert('true');
return true;
} else {
alert('false');
return false;
}
} else {
alert('Only letters please.');
}
}
takeString('This is'); // shows Only letters please which is wrong. this should work
takeString('String); // returns true which right
takeString('string'); // returns false which is right
takeString('This is 12312321'); // shows only letters please which is right bcoz it has digits
takeString('12312312'); // show Only letters please which is right.
Spaces aren't letters. You have to add them into your character set:
> 'This is a string'.match(/^[A-Za-z]+$/);
null
> 'This is a string'.match(/^[A-Za-z\s]+$/);
["This is a string"]
\s matches all whitespace, so if you don't want to match tabs, replace \s with a space.
Here's a slightly more condensed version of your code:
function takeString(str) {
return str.match(/^[A-Z][A-Za-z ]*$/);
}
along with the regex advice given by Blender, you'll want to also do the following (in order to satisfy the need to check each word ... assuming words are space or tab separated only:
use the split function to break the string into words ( var mywords = str.split(/\s+/) )
iterate over mywords array returned by split, checking each array element against the regex
return an error if the regex doesnt match
return success if you match every word
takeString (str) {
var mywords = str.split(/\s+/);
for (i = 0; i < mywords.length; i++) {
if (str.match(/^[A-Z][A-Za-z]*$/) != true) {
return false;
}
}
return true;
}
(someone needs to check my js ... )