Why do escape characters in regex mismatch? - regex

If I want to match the dot symbol (.) I have to write this regex:
/\./
Escape character is needed to match the symbol itself.
If I want to match the 'd' symbol I have to write this one:
/d/
Escape character is not needed to match the symbol itself.
And if I want to match any character (/./) or any digit character (/\d/) it's vice versa.
It seems to me that this approach is not very consistent. What is the reasoning that stands behind it?
Thank you.

The . character is a reserved regular expression keyword. The d isn't. You need to include the escape character when you match a period to explicitly tell regex that you want to use the period as a normal matching character. d by itself isn't a reserved word, so you don't need to escape it, but \d is a reserved word.
I can see how, to someone coming to regex it can be a little odd, but the . is used so often, and I can't think of a time I've really needed to match periods it just makes more sense to have it be one character without the backslash.

Related

re compile error: sre_constants.error: bad character range [duplicate]

How to rewrite the [a-zA-Z0-9!$* \t\r\n] pattern to match hyphen along with the existing characters ?
The hyphen is usually a normal character in regular expressions. Only if it’s in a character class and between two other characters does it take a special meaning.
Thus:
[-] matches a hyphen.
[abc-] matches a, b, c or a hyphen.
[-abc] matches a, b, c or a hyphen.
[ab-d] matches a, b, c or d (only here the hyphen denotes a character range).
Escape the hyphen.
[a-zA-Z0-9!$* \t\r\n\-]
UPDATE:
Never mind this answer - you can add the hyphen to the group but you don't have to escape it. See Konrad Rudolph's answer instead which does a much better job of answering and explains why.
It’s less confusing to always use an escaped hyphen, so that it doesn't have to be positionally dependent. That’s a \- inside the bracketed character class.
But there’s something else to consider. Some of those enumerated characters should possibly be written differently. In some circumstances, they definitely should.
This comparison of regex flavors says that C♯ can use some of the simpler Unicode properties. If you’re dealing with Unicode, you should probably use the general category \p{L} for all possible letters, and maybe \p{Nd} for decimal numbers. Also, if you want to accomodate all that dash punctuation, not just HYPHEN-MINUS, you should use the \p{Pd} property. You might also want to write that sequence of whitespace characters simply as \s, assuming that’s not too general for you.
All together, that works out to apattern of [\p{L}\p{Nd}\p{Pd}!$*] to match any one character from that set.
I’d likely use that anyway, even if I didn’t plan on dealing with the full Unicode set, because it’s a good habit to get into, and because these things often grow beyond their original parameters. Now when you lift it to use in other code, it will still work correctly. If you hard‐code all the characters, it won’t.
[-a-z0-9]+,[a-z0-9-]+,[a-z-0-9]+ and also [a-z-0-9]+ all are same.The hyphen between two ranges considered as a symbol.And also [a-z0-9-+()]+ this regex allow hyphen.
use "\p{Pd}" without quotes to match any type of hyphen. The '-' character is just one type of hyphen which also happens to be a special character in Regex.
Is this what you are after?
MatchCollection matches = Regex.Matches(mystring, "-");

"Match a literal character", or "match a character literally"?

I was making a RegEx using the regex101 tool and read in the explanation field
[.] - the literal character .
[\.] - matches the character . literally
I get lost between "literal character" and "character literally".
What is the difference between these two?
There is no difference. Sorry, I take that back. The only difference the words that Firas Dib, the author of regx101, chose to explain various tokens.
A literal character or matching something literally refers to specifying an actual character in the text: for instance, a to match a, as opposed to a character class such as \w that could also match a.
You can match a literal period in either of these three ways:
\.
[.]
[\.]
Which Option is Better?
Some people like option 2 because it makes it clear you are matching a period, not the catch-all dot. It stands out. For myself, I use \.. Some people will say that using a character class is less optimal, but on modern processors it makes no difference. You pick.
Option 3 is over the top and is typically used when someone doesn't know that periods don't need to be escaped inside a character class. In my view it's confusing. What did the author mean? Were they trying to create a character class to match either a backslash or a period, and made a typo? (That would be [\\.]

Period in .Net 3.5 Regex.IsMatch

I came across this regular expression in vb.net 3.5 code:
Regex.IsMatch(strString, "^[\w\s.+'\-\(\)\/\,\&\#]+$")
What is really confusing me is the ".+" part. I was under the impression that the period means any character and the plus sign means one or more. Following this, I feel like this regular expression should allow anything! But it doesn't, so I must be misunderstanding something. In testing it, it seems like the period and the plus sign are being taken as literals.
Could somebody help explain this to me?
Thanks!
The issue is that all of those characters are enclosed in a [character-group]. The escaping rules are different in character-groups than they are elsewhere in a RegEx expression. For instance, according to the MSDN documentation, \b inside a character-group means a backspace character whereas, outside of a character-group, it is an anchor that matches a word boundary.
According to the Regular-Expressions.info documentation:
In most regex flavors, the only special characters or metacharacters inside a character class are the closing bracket (]), the backslash (), the caret (^), and the hyphen (-). The usual metacharacters are normal characters inside a character class, and do not need to be escaped by a backslash.
Therefore, in your example RegEx expression, it looks for any one of the characters in that bracketed list, including either the literal . or + character. If you think about it, it wouldn't make any sense to use a . to mean "any character" inside of a character-group. Doing so would make the group, itself, moot. And certainly, using the + character to mean "one or more times" inside of a character-group really makes no sense.
.+ is mean any symbol in an amount of one or more. Maybe you need to escape dot like \.+?
Within the square parenthesis, dot and plus don't have their special meaning. The square brackets define a "character class". It does not contain a string but a set of characters allowed at this position.
So the expression [\w\s.+'-()/\,\&#] creates a character class of letters, digits, underscore, spaces, dots, pluses, single quotes, minuses, opening round brackets, closing round brackets, slashes, commas, ampersands and hashmarks.
The + behind the square parenthesis means you expect one or more characters of this character class.

What does (^?)* mean in this regex?

I have this regex:
^(^?)*\?(.*)$
If I understand correctly, this is the breakdown of what it does:
^ - start matching from the beginning of the string
(^?)* - I don't know know, but it stores it in $1
\? - matches a question mark
(.*)$ - matches anything until the end of the string
So what does (^?)* mean?
The (^?) is simply looking for the literal character ^. The ^ character in a regex pattern only has special meaning when used as the first character of the pattern or the first character in a grouping match []. When used outside those 2 positions the ^ is interpreted literally meaning in looks for the ^ character in the input string
Note: Whether or not ^ outside of the first and grouping position is interpreted literally is regex engine specific. I'm not familiar enough with LUA to state which it does
Lua does not have a conventional regexp language, it has Lua patterns in its place. While they look a lot like regexp, Lua patterns are a distinct language of their own that has a simpler set of rules and most importantly lacks grouping and alternation features.
Interpreted as a Lua pattern, the example will surprising a longtime regexp user since so many details are different.
Lua patterns are described in PiL, and at a first glance are similar enough to a conventional regexp to cause confusion. The biggest differences are probably the lack of an alternation operator |, parenthesis are only used to mark captures, quantifiers (?, -, +, and *) only apply to a character or character class, and % is the escape character not \. A big clue that this example was probably not written with Lua in mind is the lack of the Lua pattern quoting character % applied to any (or ideally, all) of the non-alphanumeric characters in the pattern string, and the suspicious use of \? which smells like a conventional regexp to match a single literal ?.
The simple answer to the question asked is: (^?)* is not a recommended form, and would match ^* or *, capturing the presence or absence of the caret. If that were the intended effect, then I would write it as (%^?)%* to make that clearer.
To see why this is the case, let's take the pattern given and analyze it as a Lua pattern. The entire pattern is:
^(^?)*\?(.*)$
Handed to string.match(), it would be interpreted as follows:
^ anchors the match to the beginning of the string.
( marks the beginning of the first capture.
^ is not at the beginning of the pattern or a character class, so it matches a literal ^ character. For clarity that should likely have been written as %^.
? matches exactly zero or one of the previous character.
) marks the end of the first capture.
* is not after something that can be quantified so it matches a literal * character. For clarity that should likely have been written as %*.
\ in a pattern matches itself, it is not an escape character in the pattern language. However, it is an escape character in a Lua short string literal, making the following character not special to the string literal parser which in this case is moot because the ? that follows was not special to it in any case. So if the pattern were enclosed in double or single quotes, then the \ would be absorbed by string parsing. If written in a long string (as [[^(^?)*\?(.*)$]], the backslash would survive the string parser, to appear in the pattern.
? matches exactly zero or one of the previous character.
( marks the beginning the second capture.
. matches any character at all, effectively a synonym for the class [\000-\255] (remember, in Lua numeric escapes are in decimal not octal as in C).
* matches zero or more of the previous character, greedily.
) marks the end of the second capture.
$ anchors the pattern to the end of the string.
So it matches and captures an optional ^ at the beginning of the string, followed by *, then an optional \ which is not captured, and captures the entire rest of the string. string.match would return two strings on success (either or both of which might be zero length), or nil on failure.
Edit: I've fixed some typos, and corrected an error in my answer, noticed by Egor in a comment. I forgot that in patterns, special symbols loose their specialness when in a spot where it can't apply. That makes the first asterisk match a literal asterisk rather than be an error. The cascade of that falls through most of the answer.
Note that if you really want a true regexp in Lua, there are libraries available that will provide it. That said, the built-in pattern language is quite powerful. If it is not sufficient, then you might be best off adopting a full parser, and use LPeg which can do everything a regexp can and more. It even comes with a module that provides a complete regexp syntax that is translated into an LPeg grammar for execution.
In this case, the (^?) refers to the previous string "^" meaning the literal character ^ as Jared has said. Check out regexlib for any further deciphering.
For all your Regex needs: http://regexlib.com/CheatSheet.aspx
It looks to me like the intent of the creator of the expression was to match any number of ^ before the question mark, but only wanted to capture the first instance of ^. However, it may not be a valid expression depending on the engine, as others have stated.

Regex doesn't recognize underscore as special character

/(?=^.{8,}$)(?=.*[_!##$%^&*-])(?=.*\d)(?=.*\W+)(?![.\n])(?=.*[a-z])(?=.*[A-Z]).*$/
I'm trying to make a regex for password validation such that the password must be at least 8 chars and include one uppercase, one lowercase, one number, and one special char. It works fine except it won't recognize the underscore (_) as a special character. I.e., Pa$$w0rd matches, but Pass_w0rd doesn't. Thoughts?
This portion of the regex seems to be looking for special characters:
(?=.*[!##$%^&*-])
Note that the character class does not include an underscore, try changing this to the following:
(?=.*[_!##$%^&*-])
You will also need to modify or remove this portion of the regex:
(?=.*\W+)
\W is equivalent to [^a-zA-Z0-9_], so if an underscore is your only special character this portion of the regex will cause it to fail. Instead, change it to the following (or remove it, it is redundant since you already check for special characters earlier):
(?=.*[^\w_])
Complete regex:
/(?=^.{8,}$)(?=.*[_!##$%^&*-])(?=.*\d)(?=.*[^\w_])(?![.\n])(?=.*[a-z])(?=.*[A-Z]).*$/
This one here works as well. It defines a special character as by excluding alphanumerical characters and whitespace, so it includes the underscore:
(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[\d])(?=.*?[^\sa-zA-Z0-9]).{8,}
The problem is that the only thing that could possibly satisfy the \W, by definition, is something other than [a-zA-Z0-9_]. The underscore is specifically not matched by \W, and in Pass_w0rd, nothing else is matched by it, either.
I suspect that having both your specific list of special characters and the \W is overkill. Pick one and you're likely to be happier. I also recommend splitting this whole thing up into several separate tests for much better maintainability.
A much simpler regex that works for you is this:
/(?=.*[_!##$%^&*-])(?=.*\d)(?!.*[.\n])(?=.*[a-z])(?=.*[A-Z])^.{8,}$/
There were few mistakes in your original regex eg:
You don't need to use lookahead for making sure there are 8 chars in input
negative lookahead [.\n] was missing .*
(?=.*\W+) is superfluous and probably not serving any purpose