Is there a way to make JSLint happy with this regex? - javascript

When running my JavaScript through JSLint, I get the following two errors from the same line of code.
Problem at line 398 character 29: Insecure '.'.
if (password.match(/.[!,#,#,$,%,^,&,*,?,_,~,-,(,)]/))
Problem at line 398 character 41: Unescaped '^'.
if (password.match(/.[!,#,#,$,%,^,&,*,?,_,~,-,(,)]/))
I understand that JSLint may be being "over-cautious". I read the comments on a similar question, Purpose of JSLint "disallow insecure in regex" option.
Nonetheless, I would like to have the best of all worlds, and have a working regular expression that also doesn't cause JSLint to complain.
But I fail at regex.
Is it possible to make regular expression that looks for the presence of at least one special character, yet doesn't cause JSLint to complain?

That's a character class; you don't need a separator (eg: the commas). You can clean up the regex by placing the caret (^) and the dash (-) in strategic positions so they don't need to be escaped.
/[!##$%^&*?_~()-]/
Should work. You can also use the non-word character class:
/\W/
That matches anything that's not a letter (a-zA-Z), number (0-9) or underscore (_).

Related

Regex Pattern Causes Catastrophic Backtracking In Edge Cases

I have these two simple regex patterns to match urls that are from these stores, but they lead to catastrophic backtracking and a frozen browser when running on some string url with an edge case. This logic is running on thousands of random requests, so the chance of catastrophic backtracking is high. Does anyone have an idea of what could be wrong in the way I wrote this regex.
> ".*://.*.newegg.com/Product/Product.*"
> ".*://.*.gamestop.com*.*Product-Variation*.*productDetailsRedesign"
You have too many greedy dot patterns in the expressions. Try be a ted bit more verbose:
\w+://[^/]*\.newegg\.com/Product/Product\S*
The second pattern:
\w+://[^\s/]*\.gamestop\.com\S*?Product-Variation\S*?productDetailsRedesign
See proof #1 | proof #2.
Use \S*? to match any characters different from whitespace (as few as possible).
Escape the period characters as they are regex metacharacters.
Use [^...] negated character classes if you know there can be no such characters between two substrings in a match.

Trying to use a new line character in a regex is causing a "new line" in my javascript code

I'll include a few images to get my point across here.
So what I'm trying to do is take ALL punctuation off of a word that comes out of an array. But it doesn't seem to be working and the biggest problem is that my \n and \r are acting as new lines.
Images:
So my Regex Code
Is becoming this
When I run it in a browser. And then I get the error message: Uncaught SyntaxError: Invalid regular expression: missing /
The missing / makes sense because the rest of the regex is now two lines below!
Using RegExr shows that it should be working
I'm sure it's dreadfully simple, but I just can't seem to spot my error!
If someone could explain the error of my ways, I would appreciate it, as I am terrible with RegExpressions! The other similar questions I've read on here have pointed out missing brackets, missing escape characters, etc.
I even tried escaping my escaped characters! ie. \\n and \\r, but that just left behind the two extra slashes each on a new line.
In case it helps: This JavaScript code is being echo'd out from PHP, but it works if I take out the \n and \r, so it shouldn't be a PHP issue.
Hopefully this is enough info, if there is something else I can add to clarify please comment!
The problem you have is that \n and \r are escape sequences and are interpreted literally as linefeed and carriage return symbols. They break the JS code (in this case, the literal regex notation).
To avoid that data corruption, when you send a regex pattern from one system to another, you'd better rely on the hex representation of the characters.
Use \u000A (or \x0A) for a line feed and \u000D (\x0D) for the carriage return.
One more remark: in the expression, there is one unescaped - that creates a range. I guess it is done on purpose, but still, a detail worth reporting. ,-\/ will match ,, -, ., and /.

Optimisation: (\\[abc] | [^abc])*

I have a long Regex (JavaScript), and it contains the following construct:
((\\\\)|(\\[abc])|([^abc]))*
The regex says:
Match any String, that doesn't contain the letters a,b and c.
In except if they're escaped by a backslash.
If the backslash is escaped (eg. \\a), also don't match these letters.
Here's a simple match-example:
eeeaeaee\aee\\\\ae\\\\\aee
I wonder if it's possible to optimise this regulat expression. This is only a little example, the actual regex I'm using is bigger, and I have lots of code twice.
I think a more logical (and likely faster) regexp would be something like:
(?:[^abc\\]|\\.)*
In other words, a backslash will escape anything, including another backslash.
Note a few things: first, if you don't need to capture parts of the match, use non-capturing groups. That buys you a little performance. Second, when there are multiple alternatives, put the most common one first.
You might get even better performance this way (try it):
[^abc\\]*(?:\\.[^abc\\]*)*
Rather than going through the alternation for each and every character, that will "eat" runs of non-special characters with a single step. Nested * can be bad news, leading to quadratic (or worse) runtime in cases where the regex doesn't match, but in this case that won't happen.
When writing this answer, I discovered that JS's regex engine has no possessive matchers. That sucks -- you could get better worst-case performance if they were available. (An important tip for working towards regex mastery: when performance testing a regex, always test cases where it does match AND where it doesn't match. The worst-case performance generally occurs when it doesn't.)
You can match any character after a backslash or any character that is not in [abc]:
(\\.|[^abc])*
That will match the exact same language.
I think it's actually more clear what you're intention is if you flip it around like:
([^abc]|\\.)*

Regex error in Netbeans not present in other editors

I have the following regular expression that works fine in my application code and other code editors have not reported a problem with it. It is used to validate a password.
/^(?=.*[A-Za-z])+(?=.*[\d])+(?=.*[^A-Za-z\d\s])+.*$/
So in other words:
Must have one letter
Must have one digit
Must have one non-letter, non-digit
Now it seems netbeans has a fairly decent regex parser and it has reported that this is an erroneous statement. But as i am new to regex I cannot spot the error. Is it due to using the positive lookahead ?= with the one or more + at the end?
When I take out the + the error goes away, but the regex stops performing in my application.
If anyone can tell me what is wrong with my expression that would be great.
The statement is used in a jQuery validation plugin that i use, if that helps. Also due to the fact I am using a plugin, I would prefer not splitting this into several smaller (clearly simpler and cleaner) expressions. That would require a great deal of work.
It never makes sense to apply a quantifier to a zero-width assertion such as a lookahead. The whole point of such assertions is that they allow you to assert that some condition is true, without consuming any of the text--that is, advancing the current match position. Some regex flavors treat that as a syntax error, while others effectively ignore the quantifier. Getting rid of those plus signs makes your regex correct:
/^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z\d\s]).*$/
If it doesn't work as expected, you may be running into the infamous IE lookahead bug. The usual workaround is to reorder things so the first lookahead is anchored at the end, like so:
/^(?=.{8,15}$)(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z\d\s]).*/
The (?=.{8,15}$) is just an example; I have no idea what your real requirements are. If you do want to impose minimum and maximum length limits, this is the ideal place to do it.

Regex character class inside character range failing intellij's jsLint inspection

What is the easiest way to rectify my failing inspection? There is no option in intellij (that I can find) to allow character classes inside a character range.
If you want to allow a literal hyphen - in a character class, you need to put it immediately after the opening [ (Refer "Character Classes" section at http://www.regular-expressions.info/reference.html) or immediately prior to the closing ] (I've found works in some languages at least), else it's deemed to signify a range.
And note also this comment by #IanMackinnon on this SO question (although I couldn't find an authoritative source for this after a very brief search): "explicitly escaping hyphens in character classes is another JSLint recommendation." - this was written in the context of literal hyphens. Regardless of if jsLint needs this or not to pass inspection, it's probably good practice to do this in order to future-proof the literal hyphen in case a future developer accidentally turns the class into a range by putting something between the (un-escaped) hyphen and the opening (or closing) bracket.
I therefore think the section of your regex that currently reads as [\w-+\s] should be re-written as [\-\w+\s]).
And the subsequent [\w-+] as [\-\w+], etc...

Categories

Resources