I need to replace some text in a javascript variable without losing case, ie.
"MAT" ==> "MATch string in db" instead of "Mat" ==> "match string in db"
Right now I'm doing this (doesn't keep the original case):
var user_str = $("#user-input").val();
var db_match = db_match.replace(new RegExp(user_str, "ig") , '<span class="u b match">' + user_str + '</span>');
I found cases where people needed to replace static text, but in my case I need to replace variable content instead.
Obviously this doesn't work either:
var user_str = $("#user-input").val();
db_match = db_match.replace(/(user_str)/ig, "<span class=u b match>$1</span>");
Any idea how to do this?
Use a group and build the regular expression
var str = "test";
var text = "Test this";
var re = new RegExp("(" + str + ")","gi");
console.log(text.replace(re, "<span>$1</span>")) //"<span>Test</span> this"
Related
I have a string like below
Hello there how are you?
I want to look for the substring 'there how' in the string. So I would do something like this
var str = "Hello there how are you?";
var term = "there how"
var res = str.match("\\s" + term + "\\s"); // # /s is used to ensure the match should be an independent phrase
But now the problem is, if I get a variation of the string, then the match doesn't occur. For example for strings like this
If there is a large amount of space between the words
Hello there how are you?
If certain letters are capitialized
Hello There How are you?
What I want to do is to ensure as long as the substring 'there how' is present in the string as a separate phrase (not like Hellothere how are you? or Hello there howare you? etc), I should be able to find a match.
How can I achieve the objective?
Thanks to #Wiktor Stribiżew, he proposed this solution below
var ss = ["Hello there how are you?", "Hello there how are you?", "Hello There How are you?"];
var term = "there how";
var rx = new RegExp("(?<!\\S)" + term.replace(/ /g, "\\s+") + "(?!\\S)", "i");
for (var i=0; i<ss.length; i++) {
var m = ss[i].match(rx) || "";
console.log(m[0]);
}
While this works in online nodejs compiler like repl https://repl.it/repls/AwkwardSpitefulAnimatronics, it won't work in regular javascript.
I get this error below in javascript for this line
var rx = new RegExp("(?<!\\S)" + term.replace(/ /g, "\\s+") + "(?!\\S)", "i");
SyntaxError: invalid regexp group
How can I achieve my objective?
Many browsers still don't support lookbehind hence you're getting that error. You may use this approach:
var ss = ["Hello there how are you?", "Hello there how are you?", "Hello, There How are you?"];
var term = "there how";
var rx = new RegExp("(?:^|\\s)(" + term.replace(/ +/g, "\\s+") + ")(?!\\S)", "gi");
var m;
for (var i=0; i<ss.length; i++) {
while(m = rx.exec(ss[i])) {
console.log('Start:', m.index, 'End:', rx.lastIndex, m[1]);
}
}
(?:^|\\s) is a non-capturing group that matches line start or a whitespace on left hand side of term.
Also note use of a capturing group to grab your desired substring from given input.
The (?<!\\S) portion of the regex string is what is causing the error, and it is happening on your regular version of JavaScript which does not support lookbehinds, even fixed width lookbehinds. One workaround would be to just use a word boundary there instead:
var rx = new RegExp("\\b" + term.replace(/ /g, "\\s+") + "(?!\\S)", "i");
Assuming your term starts and ends with word characters, \b should be sufficient to cover the behavior you want.
Below is an example using the term as part of the regex. Setup variables are from anubhava's answer.
// setup variables from other answers
var ss = ["Hello there how are you?", "Hello there how are you?", "Hello There How are you?"];
var term = "there how";
// if you want to use the term in the regex, replace the space(s) with \\s+ (1 or more spaces)
function replaceSpaces(s) {
return s.replace(/ /g, "\\s+")
}
// create regex
var pattern = new RegExp(`\\s${replaceSpaces(term)}\\s`)
// lowercase before comparing to ignore case
// if the regex needs to be case insensitive too, lowercase the output of replaceSpaces(term) as well
console.log(ss.map(s => pattern.test(s.toLowerCase())))
Depending on how you want your results to come back, you can approach the problem one of two ways. If you want the searched term to be returned exactly the way it shows up in the input, you can make the regex more general (option 1). However, if you want the results to come back matching the formatting of the search term, you can sanitize the input first to remove excess spaces and caps.
As Tim mentioned above, the \b word break should be sufficient to determine that the phrase is independent of other words in the input.
var ss = ["Hello there how are you?", "Hello there how are you?", "Hello There How are you?", "Hello There Howare you?"]
function buildRgx(term){
let spaceFix = term.split(' ').join('\\s+')
return new RegExp('\\b' + spaceFix + '\\b', 'i')
}
var generalizedSearchTerm = buildRgx("there how")
ss.forEach(str => {
let result = generalizedSearchTerm.exec(str)
if(result){
strmatch = result[0],
indexstart = result.index,
indexend = indexstart + strmatch.length
console.log(strmatch, indexstart, indexend)
} else {
console.log('no match found')
}
})
//OR sanitize the input first
console.log('OR')
function sanitizeStr(str){ return str.toLowerCase().replace(/\s+/g, ' ') }
var simpleSearchTerm = new RegExp('\\b' + "there how" + '\\b')
ss.forEach(str => {
let sanitizedString = sanitizeStr(str)
console.log(simpleSearchTerm.exec(sanitizedString))
})
I have some string that looks like this:
var string = popupLink(25, 'Any string')
I need to use a regular expression to change the number inside (note that this is a string inside of a larger string so I can't simply match and replace the number, it needs to match the full pattern, this is what I have so far:
var re = new RegExp(`popupLink\(${replace},\)`, 'g');
var replacement = `popupLink(${formFieldInsert.insertId},)`;
string = string.replace(re, replacement);
I can't figure out how to do the wildcard that will maintain the 'Any String' part inside of the Regular Expression.
If you are looking for a number, you should use \d. This will match all numbers.
For any string, you can use lazy searching (.*?), this will match any character until the next character is found.
In your replacement, you can use $1 to use the value of the first group between ( and ), so you don't lose the 'any string' value.
Now, you can simply do the following:
var newNumber = 15;
var newString = "var string = popupLink(25, 'Any string')".replace(/popupLink\(\d+, '(.*?)'\)/, "popupLink(" + newNumber + ", '$1')");
console.log(newString);
If you just need to change the number, just change the number:
string = string.replace(/popupLink\(\d+/, "popupLink(" + replacement);
Example:
var str = "var string = popupLink(25, 'Any string')";
var replacement = 42;
str = str.replace(/popupLink\(\d+/, "popupLink(" + replacement);
console.log(str);
If you really do have to match the full pattern, and "Any String" can literally be any string, it's much, much more work because you have to allow for quoted quotes, ) within quotes, etc. I don't think just a single JavaScript regex can do it, because of the nesting.
If we could assume no ) within the "Any String", then it's easy; we just look for a span of any character other than ) after the number:
str = str.replace(/(popupLink\()\d+([^)]*\))/, "$1" + replacement + "$2");
Example:
var str = "var string = popupLink(25, 'Any string')";
var replacement = 42;
str = str.replace(/(popupLink\()\d+([^)]*\))/, "$1" + replacement + "$2");
console.log(str);
I want to get a portion of a string via .substring(indexStart, indexEnd) then replace the same portion in the original string.
var portion = "my new house".substring(3, 6),
portion = "old";
// what's next?
You could take the surrounding substrings and concatenate:
var str = "my new house";
str = str.slice(0, 3) + "old" + str.slice(6);
console.log(str); // "my old house"
Of course, this is assuming you want to replace parts of the string marked off by certain indeces. If you just want to replace a word, you would use:
str = str.replace(/new/g, 'old');
(Omit the global flag to only replace the first occurrence.)
You just need to call 'replace' on the original string to find the substring you gathered and replace it with the new desired string.
var oldString = "my new house my new house";
var subStr = oldString.substring(indexStart, indexEnd);
var newValue = "old";
var newString = oldString.replace(subStr, newValue);
We have a string:
var dynamicString = "This isn't so dynamic, but it will be in real life.";
User types in some input:
var userInput = "REAL";
I want to match on this input, and wrap it with a span to highlight it:
var result = " ... but it will be in <span class='highlight'>real</span> life.";
So I use some RegExp magic to do that:
// Escapes user input,
var searchString = userInput.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Now we make a regex that matches *all* instances
// and (most important point) is case-insensitive.
var searchRegex = new RegExp(searchString , 'ig');
// Now we highlight the matches on the dynamic string:
dynamicString = dynamicString.replace(reg, '<span class="highlight">' + userInput + '</span>');
This is all great, except here is the result:
console.log(dynamicString);
// -> " ... but it will be in <span class='highlight'>REAL</span> life.";
I replaced the content with the user's input, which means the text now gets the user's dirty case-insensitivity.
How do I wrap all matches with the span shown above, while maintaining the original value of the matches?
Figured out, the ideal result would be:
// user inputs 'REAL',
// We get:
console.log(dynamicString);
// -> " ... but it will be in <span class='highlight'>real</span> life.";
You'd use regex capturing groups and backreferences to capture the match and insert it in the string
var searchRegex = new RegExp('('+userInput+')' , 'ig');
dynamicString = dynamicString.replace(searchRegex, '<span class="highlight">$1</span>');
FIDDLE
You can use it without capturing groups too.
dynamicString = text.replace(new RegExp(userInput, 'ig'), '<span class="highlight">$&</span>');
I am trying to match something like [allchar] with a regular expression and be able to pull it out and replace it with other content
Here is what I am trying
var text = "[abc123.;.] this is more content";
var replacewith = "[contentreplacedwith]";
reg = new RegExp("/\[{1}.*?\]{1}/g");
if(reg.test(text))
{
txt = $('#message').val().replace(text,'[' + replacewith + ']');
console.log(txt);
}
The result should be
[contentreplacedwith] this is more content
reg = new RegExp("\\[.*?\\]", "g");
x = "[abc123.;.] this is more content";
console.log(x.replace(reg, "[contentreplacedwith]"));
If you use RegExp constructor the there's no need to pass / delimiters and the options like g for global are a second argument.