Uncaught SyntaxError: Invalid regular expression in Chrome, FF and IE fine - javascript

This line of code:
if ( new RegExp("\\b" + arrCategorySort[i]+ "\\b", "g").test(titleText) )
{
catFound = true;
}
works perfect in Firefox (6.0), and in IE (7.0), but not in Chrome (13.0.782.112)
do you have any idea why?

Put a try/catch around your code and display the value that is causing the exception :
try {
if ( new RegExp("\\b" + arrCategorySort[i]+ "\\b", "g").test(titleText) )
catFound = true;
}
catch (e) {
confirm (e + ' : at index ' + i + ', category is "' + arrCategorySort[i] + '"');
}

The problem is that your arrCategorySort[i] as a string contains special characters as far as the RegExp parser is concerned (e.g. {} and []). With your string in place, you're trying to parse regexp
/\bfunction (a,b){var c=b||window,d=[];for(var e=0,f=this.length;e<f;++e){if(!a.call(c,this[e],e,this))continue;d.push(this[e])‌​}return d}\b/
After your (a,b) in the beginning, in {} you have var ... however {} mean repeated pattern and expect to have a number between them (or two numbers). What you really need is to escape all special chars: {}[]|()\,.*+ - by prepending '\' character in front of each of them. (There may be a couple more, escapes me at the moment.)

Related

Node.JS not appending string weird bug?

function getStatementValue(view, statement){ // vars "#extends('parentview') ", 'extends'
var parentname = "";
view.replace(new RegExp(/\B#\w+\('([^(')\W]+)'\)\s/, 'm'), function(occurance){
parentname = occurance.replace('#' + statement + '(\'', '')
.replace('\')', "");
console.log(parentname) // parentview
console.log(parentname + 'test') // testntview <- unexpected result
});
return parentname;
}
I've got no clue to how that result is appearing.
when I add the string as shown in console.log, it replaces the string from the beginning, almost like it's re-assigning the memory space. Is this supposed to be happening? How do I return the correct parentviewtest result?
parentname = occurance.replace('#' + statement + '(\'', '')
.replace('\')', "").trim();
Solved it by adding a .trim() to the string modification. My input included invisible \r and \n characters that I was unaware of.
Thanks to #JaromandaX for spotting that out

How to manually escape a character in JavaScript

I'm not sure how to phrase this correctly. Basically, I want to take a string composed of a backslash an an "escapable" character and convert it to the actual escaped form:
console.log(magicStringFunction('\\n') === '\n') // true
What I'm trying to do is effectively the inverse of String.raw:
console.log(String.raw`\n` === '\\n') // true
I am aware that I can technically do this with eval:
console.log(eval('"\\n"')); // \n
However, I generally like to avoid using eval. Is there a way to do this with native code?
Found an answer! Just goes to show that I need to do a bit more investigating before asking a question...
You can use JSON.parse, which is similar to eval in this case, but less dangerous and (I believe) faster.
console.log(JSON.parse('"\\n"') === '\n') // true
This is one of your proposed solution:
function magicStringFunction(w){
return JSON.parse('"' + w + '"');
}
But it will fail when this happens:
magicStringFunction('"\\n"'); // whoops
A version that prevents this from happening:
function magicStringFunction(w){
return w.replace(/\\./g, function(match){
return JSON.parse('"' + match + '"');
});
}
Might not be exactly very efficient but it works.
Or if you are not a big fan of JSON.parse for efficiency, you can do this instead:
function magicStringFunction(w){
// Defined by Table 34 under section 11.8.4.3
// ' " \ b f n r t v
var escCharMap = {
"\\'": "'",
"\\\"": "\"",
"\\\\": "\\",
"\\b": "\b",
"\\f": "\f",
"\\n": "\n",
"\\r": "\r",
"\\t": "\t",
"\\v": "\v"
};
return w.replace(/\\./g, function(match){
if(escCharMap.hasOwnProperty(match)) return escCharMap[match];
else return match.substr(1, 1);
});
}
Ref: http://www.ecma-international.org/ecma-262/7.0/index.html#prod-SingleEscapeCharacter

match word not capitalized a certain way

I want a regular expression that matches all instances of "capitalizedExactlyThisWay" that are not capitalizedExactlyThisWay.
I created a function that finds the indexes of all case insensitive matches and then pushes the values back in like this (JSBIN)
But I would rather just say something like text.replace(regexp,"<highlight>$1</highlight>");
replace has a callback function too.
s = s.replace(reg1, function(m){
if(m===word) return m;
return '<highlight>'+m+'</highlight>';
});
Unfortunately JavaScript regular expressions do not support making only a part of the expression case-insensitive.
You could write a little helper function that does the dirty work:
function capitalizationSensitiveRegex(word) {
var chars = word.split(""), i;
for (i = 0; i < chars.length; i++) {
chars[i] = "[" + chars[i].toLowerCase() + chars[i].toUpperCase() + "]";
}
return new RegExp("(?=\\b" + chars.join("") + "\\b)(?!" + word + ").{" + word.length + "}", "g");
}
Result:
capitalizationSensitiveRegex("capitalizedExactlyThisWay");
=> /(?=\b[cC][aA][pP][iI][tT][aA][lL][iI][zZ][eE][dD][eE][xX][aA][cC][tT][lL][yY][tT][hH][iI][sS][wW][aA][yY]\b)(?!capitalizedExactlyThisWay).{25}/g
Note that this assumes ASCII letters due to limitations of how \b works in JavaScript. It also assumes you're not using any regex meta characters in word (brackets, backslashes, parentheses, stars, dots, etc). An extra step of regex-quoting each char is necessary to make the above stable.
You can use match and map method with a callback:
tok=[], input.match(/\bcapitalizedexactlythisway\b/ig).map( function (m) {
if (m!="capitalizedExactlyThisWay") tok.push(m); });
console.log( tok );
["capitalizedEXACTLYTHISWAY", "capitalizedexactlYthisWay", "capitalizedexactlythisway"]
You could try this regex to match all the case-insensitive exactlythisway string but not of ExactlyThisWay ,
\bcapitalized(?!ExactlyThisWay)(?:[Ee][Xx][Aa][Cc][Tt][Ll][Yy][Tt][Hh][Ii][Ss][Ww][Aa][Yy])\b
Demo
If you could somehow get JavaScript to work with partial case-insensitive matching, i.e. (?i), you could use the following expression:
capitalized(?!ExactlyThisWay)(?i)exactlythisway
If not, you're probably stuck with something like this:
capitalized(?!ExactlyThisWay)[a-zA-Z]+
The downside is that it will also match other variations such as capitalizedfoobar etc.
Demo

Javascript Dynamic Regex Generation

I want to make my alphanumeric regex dynamic in a way that it takes the allowed special characters with it as an argument by the user. Following is my code ... I am getting quotes error here .... any body can tell me how to go about it ?
function aplhanumeric(value,allowed){
///^[a-z0-9_\-]+$/i
alert(allowed);
if(allowed != ''){
var regex = new RegExp('/^[a-z0-9_\' + allowed + ']+$/i');
return (value.match(regex));
}else{
return (alphaNumericRegex.test(value));
}
}
You've actually escaped the quote, so you have to escape the escape
var regex = new RegExp("^[a-z0-9_\\" + allowed + "]+$", "i");

Alpha-numeric with whitespace regex

Just when you think you've got a handle on regex; it all comes undone. Hoping to return a false check if anything other than alpha numeric and whitespace characters are found.
function checkName(fname)
{
var rexp = new RegExp(/[^a-zA-Z0-9]\s/gim)
if (!rexp.test(fname))
{
alert ("'" + fname + "'\nis okay")
}
else
{
alert ("'" + fname + "'\nis NOT okay")
}
return !rexp.test(fname)
}
I would hope that the above code would return for the following
"This is ok" - true
"This, is not ok" -false
"Nor is this ok!" -false
"Nor is \"this ok" - false
Although much of the discussion is right, everything seems to be missing the point that you are inverting character classes and then inverting the results in your function. This is logically hard to read. You also do two tests on the regex for no good reason. Much cleaner would be something like this:
function checkName(fname) {
var result = /^[a-z0-9\s]+$/i.test(fname)
if (result) {
alert ("'" + fname + "'\nis okay")
} else {
alert ("'" + fname + "'\nis NOT okay")
}
return result;
}
Update: It looks like Jack's edits captured these points too. (Always a minute late and a nickel short...)
[^a-zA-Z0-9]\s
Your regex requires the whitespace to be after the letters/numbers.
To fix it, move the \s inside the brackets.
You still have to do one more thing though. The regex will only match one of these characters. Add a + to match one or more.
Therefore, fixed regex:
[^a-zA-Z0-9\s]+
A few things:
/something/ is the short notation for new RegExp('something'); you shouldn't mix them up.
You need to move the \s inside the character class; otherwise you match a character that's not alphanumeric followed by a space.
I don't think you need all those modifiers:
/m is only useful if you have anchors in your expression,
/i can be used if you remove A-Z or a-z from the character class,
/g is only useful for when you need to match multiple times, but in your case the first match is enough.
var rexp = /[^a-zA-Z0-9\s]/;
The whole function can be written like this:
function checkName(fname)
{
return !/[^a-zA-Z0-9\s]/.test(fname);
}
Instead of using double negatives, it would be better to say "only allow these characters":
function checkName(fname)
{
return /^[a-zA-Z0-9\s]*$/.test(fname);
}
If you need to test for non-empty names as well, you should use /^[a-zA-Z0-9\s]+$/.
Try:
function checkName(fname)
{
var rexp = new RegExp(/^[a-z0-9\s]+$/i)
if (!rexp.test(fname))
{
alert ("'" + fname + "'\nis okay")
}
else
{
alert ("'" + fname + "'\nis NOT okay")
}
return !rexp.test(fname)
}

Categories

Resources