1

Why does this regex not match 3a?

(\/\d{1,4}?|\d{1,4}?|\d{1,4}[A-z]{1})

Using \d{1,4}\D{1}, the result is the same.

Streets numbers:

/1
78
3a
89/
-1 (special case)
1

https://regex101.com/r/cYCafR/3

sawa
  • 165,429
  • 45
  • 277
  • 381
  • Because `\d{1,4}?` matches them and `\d{1,4}[A-z]{1}` does not even have a chance to step in. Besides, `[A-z]` is a typo, it should be `[A-Za-z]`. It seems you want [`\d{1,4}[A-Za-z]|\/?\d{1,4}`](https://regex101.com/r/tdzSc5/1). Well, if it should be at the start of a line, [`^(?:\d{1,4}[A-Za-z]|\/?\d{1,4})`](https://regex101.com/r/tdzSc5/2). – Wiktor Stribiżew Jul 18 '18 at 07:47

2 Answers2

3

The digits+letter combination is not matched due to the order of alternatives in your pattern. The \d{1,4}? matches the digit before the letter, and \d{1,4}[A-z]{1} does not even have a chance to step in. See the Remember That The Regex Engine Is Eager article.

The \/\d{1,4}? will match a / and a single digit after the slash, and \d{1,4}? will always match a single digit, as {min,max}? is a lazy range/interval/limiting quantifier and as such only matches as few chars as possible. See Laziness Instead of Greediness.

Besides, [A-z] is a typo, it should be [A-Za-z].

It seems you want

\d{1,4}[A-Za-z]|\/?\d{1,4}

See the regex demo. If it should be at the start of a line, use

 ^(?:\d{1,4}[A-Za-z]|\/?\d{1,4})

See this regex demo.

Details

  • ^ - start of a line
  • (?: - start of a non-capturing group
    • \d{1,4}[A-Za-z] - 1 to 4 digits and an ASCII letter
    • | - or
    • \/? - an optional /
    • \d{1,4} - 1 to 4 digits
  • ) - end of the group.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Actually A-z is from one street address regex from stack overflow some user example. I do not have time to search it again but, thank you for your time and useful links! – MysteriousNothing Jul 18 '18 at 08:11
  • @MysteriousNothing That is a very common typo, it is even present in some regex tutorials online. There is only one environment, where `[A-z]` will work as expected, but it is certainly not Ruby. – Wiktor Stribiżew Jul 18 '18 at 08:13
  • @MysteriousNothing Lots of code contains mistakes. Just because you found the code somewhere on the internet, that doesn't make it right ;) – Tom Lord Jul 18 '18 at 08:43
  • @TomLord But, but, it was on stack overflow and up voted :D [A-z] part was on there, other is my own stupidity. – MysteriousNothing Jul 18 '18 at 08:57
  • @MysteriousNothing You must be talking about [this post](https://stackoverflow.com/a/6067606/3832970). Read the **Update**. Although rather than writing something below that subtitle the user who posted the answer should have updated the solution at the top. – Wiktor Stribiżew Jul 18 '18 at 09:09
1

Your regex uses lazy quantifiers like {1,4}?. These will match one character, and stop, because the rest of the pattern (i.e. nothing) matches the rest of the string. See here for how greedy vs lazy quantifiers work.

Another reason is that you put the \d{1,4}[A-z]{1} case last. This case will only be tried if the first two cases don't match. With 3a, the 3 already matches the second case, so the last case won't be considered.

You seem to just want:

^(\d{1,4}[A-Za-z]|\/?\d{1,4})

Note how the \/\d{1,4} case and the \d{1,4} case in your original regex are combined into one case \/?\d{1,4}.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I have so much to learn, helpful articles for beginner like me, really thank you taking your time! – MysteriousNothing Jul 18 '18 at 08:08
  • @MysteriousNothing If you think the answers answer your question, please consider selecting the answer that you think is the best and accept it by clicking on that checkmark! – Sweeper Jul 18 '18 at 08:12
  • both answers was helpful and tips and had useful tips so I select who posted first. I hope no hard feelings. :) – MysteriousNothing Jul 18 '18 at 08:24
  • Mysterious, I have no comment on your selection for awarding the greenie, but I see no reason that an answer's timestamp should have anything to do with it. If you were asked which of two pizzas you preferred would the tie-breaker be the one you ate first? – Cary Swoveland Jul 18 '18 at 18:20