-1

Fiddle at http://jsfiddle.net/42zcL/

I have the following code, which should alert "No Match". If I put the regex into regexpal.com and run it, it doesn't match (as expected). With this code, it does match. I know there is another way to do it, which works correctly - /^((.*)Waiting(.*))?$/, but I am curious as to why this one fails. It should match a string with the text "Waiting" in it or nothing at all.

var teststring="Anything";
if (teststring.match(/^((.*)Waiting(.*))|()$/)) alert('match');
else alert('No Match');

EDIT: Clearer example:

var teststring="b";
if (teststring.match(/^(a)|()$/)) alert('match');
else alert('No Match');

Produces a Match, when I would expect "No Match"

Expected behaviour, as per regexpal.com:

teststring: a = match
teststring: b = no match

Actual behaviour in javascript:

teststring: a = match
teststring: b = match
7
  • 2
    ^a|b$ matches a string beginning with a or a string ending with b. You appear to be looking for ^(a|b)$. (Or ^(?:a|b)$.) Commented Feb 1, 2014 at 5:29
  • I want to match successfully on either a string matching 'Waiting' or an empty string, which I thought the original one would do and I am surprised that it does in regexpal but doesn't in javascript. Commented Feb 1, 2014 at 5:32
  • Why not just use teststring.indexOf("Waiting"), though? Commented Feb 1, 2014 at 5:34
  • I want it to do one thing if it's blank, "Waiting 1", "2 Waiting" or anything else with Waiting in it and something else if it's not blank, but also not containing Waiting. Anyway, I have a solution, I am wondering why it matches in javascript (when I believe it shouldn't) and not in regexpal.com Commented Feb 1, 2014 at 5:37
  • First, I updated with more detail in my answer for you and second, regexpal.com actually does match it. The highlighting of the characters around "Waiting" show what is producing a match. Even with nothing to test against it still matches positively. Potentially my edit will help you understand why this happens. Commented Feb 1, 2014 at 5:56

1 Answer 1

2

Because you have |()$ at the end which is like saying "Match what comes before | but if you don't find it, match anything as long as there's an end of line."

- Full RegEx reference

- Try it out

Hopefully this explains it a little better:

  1. The use of () in RegEx does not mean "Don't match anything". If no characters are specified it will still match against () at each position in the string (letter position that is). Imagine it like this: The word "Anything" turned into an array - [A,n,y,t,h,i,n,g] - if n = length of that array, the placeholder at [n] is non-empty, resulting in a "match" since no specific restriction was expressed in the pattern.
  2. Since #1 essentially means |()$ will return a positive result on any word tested, you will always see "match" in your alert.

I'm pretty terrible at conveying my thoughts so maybe this previous stack answer will fill in whatever holes my answer left open.

Sign up to request clarification or add additional context in comments.

4 Comments

Except I start with ^ so it should be saying from the start match either what comes before | or nothing before the end of the line. Or am I misunderstanding something? Why does it work in regexpal?
Incidentally, your "try it out" link shows the opposite result than my jsfiddle, again showing that something is out of whack and I am curious as to what :)
Thanks for the edit. I understand that |()$ will return a positive result on any word, but I didn't think that ^(stuff)|()$ would do so because of the ^
The pipe is saying 'this OR that' so the first expression is tested, which in your example will fail, then it tries the second expression. Which as Deryck says matches anything that has an end of line. The ^ only counts for the first expression.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.