4

I made the following regex:

(\d{5}|\d-\d{4}|\d{2}-\d{3}|\d{3}-\d{2}|\d{4}-\d)

And it seems to work. That is, it will match a 5 digit number or a 5 digit number with only 1 hyphen in it, but the hyphen can not be the lead or the end.

I would like a similar regex, but for a 25 digit number. If I use the same tactic as above, the regex will be very long.

Can anyone suggest a simpler regex?

Additional Notes: I'm putting this regex into an XML file which is to be consumed by an ASP.NET application. I don't have access to the .net backend code. But I suspect they would do something liek this:

Match match = Regex.Match("Something goes here", "my regex", RegexOptions.None);
Oli
  • 591
  • 4
  • 10
John
  • 32,403
  • 80
  • 251
  • 422

5 Answers5

10

You need to use a lookahead:

^(?:\d{25}|(?=\d+-\d+$)[\d\-]{26})$

Explanation:

  • Either it's \d{25} from start to end, 25 digits.
  • Or: it is 26 characters of [\d\-] (digits or hyphen) AND it matched \d+-\d+ - meaning it has exactly one hyphen in the middle.

Regular expression visualization

Working example with test cases

Community
  • 1
  • 1
Kobi
  • 135,331
  • 41
  • 252
  • 292
  • Here's another version using the stack for counting, and having the number 25 only once: `^(?\d)+(?:-(?\d)+)?$(?<-Digit>){25}(?(Digit)(?!))` – Kobi Aug 22 '13 at 19:55
  • This will match 25 digits with zero hyphens as well. – pguardiario Aug 22 '13 at 22:13
  • @pguardiario - It sure will. Isn't that what the OP wanted? John had `\d{5}` as the first alternation. – Kobi Aug 23 '13 at 09:10
5

You could use this regex:

^[0-9](?:(?=[0-9]*-[0-9]*$)[0-9-]{24}|[0-9]{23})[0-9]$

The lookahead makes sure there's only 1 dash and the character class makes sure there are 23 numbers between the first and the last. Might be made shorter though I think.

EDIT: The a 'bit' shorter xP

^(?:[0-9]{25}|(?=[^-]+-[^-]+$)[0-9-]{26})$

A bit similar to Kobi's though, I admit.

Jerry
  • 70,495
  • 13
  • 100
  • 144
  • I don't know anything about the asp.net regex engine. But does it support infinite length lookaheads? – FDinoff Aug 22 '13 at 19:28
  • @FDinoff Yup! Sure does. – Jerry Aug 22 '13 at 19:29
  • @FDinoff - are there Regex flavors that don't support variable length lookaheads? I know lookbehinds are not usually supported (.net has these too, by the way). – Kobi Aug 22 '13 at 19:37
  • thakns guys! i like it, I picked kobi's because he gave me a pretty picture – John Aug 22 '13 at 19:39
  • @Kobi I don't know. I just assumed if variable length look behinds weren't supported in some languages lookaheads wouldn't be either. Bad assumption on my part I guess – FDinoff Aug 22 '13 at 19:46
0

If you aren't fussy about the length at all (i.e. you only want a string of digits with an optional hyphen) you could use:

([\d]+-[\d]+){1}|\d

(You may want to add line/word boundaries to this, depending on your circumstances)

If you need to have a specific length of match, this pattern doesn't really work. Kobi's answer is probably a better fit for you.

Obsidian Phoenix
  • 4,083
  • 1
  • 22
  • 60
0

I think the fastest way is to do a simple match then add up the length of the capture buffers, why attempt math in a regex, makes no sence.

 ^(\d+)-?(\d+)$
0

This will match 25 digits and exactly one hyphen in the middle:

^(?=(-*\d){25})\d.{24}\d$
pguardiario
  • 53,827
  • 19
  • 119
  • 159