I'm replacing a sub-string using replace function and regex expression.
However after character escape and replacement, I still have an extra '/' character. I'm not really familiar with regex can someone guide me.
I have implemented the escape character function found here: Is there a RegExp.escape function in Javascript?
RegExp.escape= function(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
const latexConversions = [
["\\cdot", "*"],
["\\right\)", ")"],
["\\left\(", "("],
["\\pi", "pi"],
["\\ln\((.*?)\)", "log($1)"],
["stdev\((.*?)\)", "std($1)"],
["stdevp\((.*?)\)", "std(\[$1\], \"uncorrected\")"],
["mean\((.*?)\)", "mean($1)"],
["\\sqrt\((.*?)\)", "sqrt($1)"],
["\\log\((.*?)\)", "log10($1)"],
["\(e\)", "e"],
["\\exp\((.*?)\)", "exp($1)"],
["round\((.*?)\)", "round($1)"],
["npr\((.*?),(.*?)\)", "($1!/($1-$2)!)"],
["ncr\((.*?),(.*?)\)", "($1!/($2!($1-$2)!))"],
["\\left\|", "abs("],
["\\right\|", ")"],
];
RegExp.escape = function (s) {
var t = s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return t;
};
mathematicalExpression = "\\sqrt( )"
//Problem is here
mathematicalExpression = mathematicalExpression.replace(new RegExp(RegExp.escape(latexConversions[8][0]), 'g'), latexConversions[8][1]);
//Works
mathematicalExpression2 = mathematicalExpression.replace(/\\sqrt\((.*?)\)/g, "sqrt($1)");
alert("what I got: "+mathematicalExpression); // "\sqrt()"
alert("Supposed to be: "+ mathematicalExpression2); // "sqtr()"
I have a live example here: https://jsfiddle.net/nky342h5/2/
There are several misconceptions regarding the string literal "\\sqrt\((.*?)\)":
This string in raw characters is: \sqrt((.*?)). Note how there is no difference between the two opening parentheses: the backslash in the string literal was not very useful. In other words, "\(" === "("
Both opening parentheses will be escaped by RegExp.escape
Points 1 and 2 are equally true for the closing parentheses, for the dot, the asterisk and the question mark: they will be escaped by RegExp.escape.
In short, you have no way to distinguish that a character is intended as a literal or as a regex special symbol -- you are escaping all of them as if they were intended as literal characters.
The solution:
Since you already are encoding regex specific syntax in your strings (like (.*?)), you might as well use regex literals instead of string literals.
In the case you highlighted, instead of this:
["\\sqrt\((.*?)\)", "sqrt($1)"]
...use this:
[/\\sqrt\((.*?)\)/g, "sqrt($1)"]
And let your code do:
mathematicalExpression = mathematicalExpression.replace(...latexConversions[8]);
Alternative
If for some reason regex literals are a no-go, then define your own special syntax for (.*?). For instance, use the symbol µ to denote that particular regex syntax.
Then your array pair would look like this:
["\\sqrt(µ)", "sqrt($1)"],
...and code:
mathematicalExpression = mathematicalExpression.replace(
new RegExp(RegExp.escape(latexConversions[8][0]).replace(/µ/g, '(.*?)'), 'g'),
latexConversions[8][1]
);
Note how here the (.*?) is introduced in the string after RegExp.escape has done its job.
extra \ rather than escaping everything
replace ["\\sqrt\((.*?)\)", "sqrt($1)"], with ["\\\\sqrt\((.*?)\)", "sqrt($1)"],
and replace the final replace with
mathematicalExpression = mathematicalExpression.replace(new RegExp((latexConversions1[8][0]), 'g'), latexConversions1[8][1]);
Related
I have this regex that matches something like [abc] as a string pattern, with the help of
"[]": "((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)
So it will catch [ABC] from ABC A B [ABC] BC. So anything enclosed in a square bracket.
It works as it's supposed to.
Then I wrote an expression like
"{{}}": "((\\{\\{[^\\}\\}]*($|\\}\\}))(\\}\\}[^\\}\\}]*($|\\}\\}))*)"
to catch something like {{abc}}. Now, this does work in online regex testers, it catches {{abc}} from ABC A B {{ABC}} BC.
But it's not doing anything when I have it in a JS code. While, the square bracket expression does what it's supposed to. Am I missing something?
I don't see the problem. I also tried to use your code and it seems to work:
function createStringRegex(stringTypes) {
return new RegExp('^(' + this.createStringPattern(stringTypes) + ')', 'u');
}
// This enables the following string patterns:
// 1. backtick quoted string using `` to escape
// 2. square bracket quoted string (SQL Server) using ]] to escape
// 3. double quoted string using "" or \" to escape
function createStringPattern(stringTypes) {
const patterns = {
'``': '((`[^`]*($|`))+)',
'[]': '((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)',
"{{}}": "((\\{\\{[^\\}\\}]*($|\\}\\}))(\\}\\}[^\\}\\}]*($|\\}\\}))*)",
'""': '(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)',
"''": "(('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"N''": "((N'[^N'\\\\]*(?:\\\\.[^N'\\\\]*)*('|$))+)"
};
return stringTypes.map(t => patterns[t]).join('|');
}
console.log("[abc]".match(createStringRegex(["[]"]))); // it matches
console.log("{{abc}}".match(createStringRegex(["{{}}"]))); // it matches
console.log("[abc]".match(createStringRegex(["{{}}"]))); // it doesn't match
I have a string that has some double quotes escaped and some not escaped.
Like this,
var a = "abcd\\\"\""
a = a.replace(/\[^\\\]\"/g, 'bcde')
console.log(a)
The string translates to literal, abcd\"".
Now, i am using the above regex to replace non-escaped double quotes.
And only the second double quote must be replaced.
The result must look like this,
abcd\"bcde
But it is returing the same original string, abcd\"" with no replacement.
You can use capture group here:
a = a.replace(/(^|[^\\])"/g, '$1bcde')
//=> abcd\"bcde
A negative lookbehind is what you want. However it is not supported in the Regex' JS flavor.
You can achieve this by processing the result in two steps:
var a = "abcd\\\"\"";
console.log(a);
var result = a.replace(/(\\)?"/g, function($0,$1){ return $1?$0:'{REMOVED}';});
console.log(result);
I'm looking for a function that does replaceAll with any start and endcharacter.
I know I can use the regex notation:
string=string.replace(/a/g,"b");
However, because the searched char is in a regex, I sometimes need to escape that character and sometimes not, which is annoying if I want to do this for a full list of chars
convertEncoding= function(string) {
var charMap= {'"':""",'&':"&",...}
for (startChar in charMap) {
endChar=charMap[startChar];
string= string.replaceAll(startChar,endChar);
}
}
Is they a good way to write that function replaceAll, without doing a for loop and using String.replace() (eg the naive way) ?
you can use escape the RegExp special characters in the strings such as described here https://stackoverflow.com/a/6969486/519995:
and then you can use the regexp global replace
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
for (startChar in charMap) {
endChar=charMap[startChar];
result = string.replace(RegExp(escapeRegExp(startChar), 'g'), endChar);
}
I have a String that I need to strip out all the spaces except for what between "". Here is the Regex that I am using to strip out spaces.
str.replace(/\s/g, "");
I cant seem to figure out how to get it to ignore spaces between quotes.
Example
str = 'Here is my example "leave spaces here", ok im done'
Output = 'Hereismyexample"leave spaces here",okimdone'
Another way to do it. This has the assumption that no escaping is allowed within double quoted part of the string (e.g. no "leave \" space \" here"), but can be easily modified to allow it.
str.replace(/([^"]+)|("[^"]+")/g, function($0, $1, $2) {
if ($1) {
return $1.replace(/\s/g, '');
} else {
return $2;
}
});
Modified regex to allow escape of " within quoted string:
/([^"]+)|("(?:[^"\\]|\\.)+")/
var output = input.split('"').map(function(v,i){
return i%2 ? v : v.replace(/\s/g, "");
}).join('"');
Note that I renamed the variables because I can't write code with a variable whose name starts with an uppercase and especially when it's a standard constructor of the language. I'd suggest you stick with those guidelines when in doubt.
Rob, resurrecting this question because it had a simple solution that only required one replace call, not two. (Found your question while doing some research for a regex bounty quest.)
The regex is quite short:
"[^"]+"|( )
The left side of the alternation matches complete quoted strings. We will ignore these matches. The right side matches and captures spaces to Group 1, and we know they are the right spaced because they were not matched by the expression on the left.
Here is working code (see demo):
var subject = 'Here is my example "leave spaces here", ok im done';
var regex = /"[^"]+"|( )/g;
replaced = subject.replace(regex, function(m, group1) {
if (group1 == "" ) return m;
else return "";
});
document.write(replaced);
Reference
How to match pattern except in situations s1, s2, s3
How to match a pattern unless...
hidValue="javaScript:java";
replaceStr = "java";
resultStr=hidValue.replace("/\b"+replaceStr+"\b/gi","");
resultStr still contains "javaScript:java"
The above code is not replacing the exact string java. But when I change the code and directly pass the value 'java' it's getting replaced correctly i.e
hidValue="javaScript:java";
resultStr=hidValue.replace(/\bjava\b/gi,"");
resultStr contains "javaScript:"
So how should I pass a variable to replace function such that only the exact match is replaced.
The replace-function does not take a string as first argument but a RegExp-object. You may not mix those two up. To create a RexExp-object out of a combined string, use the appropriate constructor:
resultStr=hidValue.replace(new RegExp("\\b"+replaceStr+"\\b","gi"),"");
Note the double backslashes: You want a backslash in your Regular Expression, but a backslash also serves as escape character in the string, so you'll have to double it.
Notice that in one case you're passing a regular expression literal /\bjava\b/gi, and in the other you're passing a string "/\bjava\b/gi". When using a string as the pattern, String.replace will look for that string, it will not treat the pattern as a regular expression.
If you need to make a regular expression using variables, do it like so:
new RegExp("\\b" + replaceStr + "\\b", "gi")
See:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace
`let msisdn = '5093240556699'
let isdnWith = numb.msisdn.slice(8,11);
let msisdnNew = msisdn.replace(isdnWith, 'XXX', 'gi');
show 5093240556XXX`