As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/
Options

Regular Expression Help

foggratfoggrat Registered User regular
edited July 2008 in Help / Advice Forum
I've avoided regular expressions like the plague, but I have a perfect use for one, so I'd like to make it happen. I've been working on it for awhile using a couple online references, but I just can't get it quite right. What I need is a regular expression that returns true for

"a string containing between 5-10 characters (a-z or A-Z or 0-9), with at least 1 digit"

Good input: abc123, 12345, 00ABCD, 12GG33

Bad input: ab12 (too short), abcbe (no number), _00ABCD (special character), GG1234567890 (too long)

So far, the best I've come up with is

[a-zA-Z0-9]{4,9}\d+

which is problematic in two ways:

1. It allows any number of digits at the end, even if it exceeds a total of 10 chars. I could live with this, BUT

2. It forces the last character to be a number. I'm fine with a string like 1ABCDE, but this expression won't work with that, and that's a deal breaker for me.

Any regular expression guru can lend me a hand? Would be much appreciated.

foggrat on

Posts

  • Options
    Premier kakosPremier kakos Registered User, ClubPA regular
    edited July 2008
    What regular expression engine are we talking about? Certain engines allow for conditionals, some don't.

    That being said, here's an ugly, brute force way of doing it that should work with anything. This, BTW, is incredibly ugly and I'm ashamed to even post it here, but it should work. I'll ponder this a little more and see if I can come up with something more elegant.

    *ugly regex edited out for ugliness*

    Premier kakos on
  • Options
    Premier kakosPremier kakos Registered User, ClubPA regular
    edited July 2008
    Duh.

    \b(?=[a-zA-Z0-9]{0,9}\d)[a-zA-Z0-9]{5,10}\b

    That uses a look-ahead assertion. Look-ahead assertions match, but don't capture. Only if they match, can the entire regular expression match. So, this particular one does a look-ahead assertion to see if there is a digit in the next 1-10 characters. If that matches, then capture the five to ten characters. I surrounded it with \b so it doesn't match subsections of non-qualifying strings.

    Premier kakos on
  • Options
    foggratfoggrat Registered User regular
    edited July 2008
    Thanks very much for the reply, I'll plug it in tommorrow and hopefully that does the trick, I don't want to have to do any brute forcing if I can help it.

    For the record, I'm using it in ASP/VB.net regexp validator, I didn't realize the engine made a difference.

    Thanks again.

    foggrat on
  • Options
    Premier kakosPremier kakos Registered User, ClubPA regular
    edited July 2008
    foggrat wrote: »
    Thanks very much for the reply, I'll plug it in tommorrow and hopefully that does the trick, I don't want to have to do any brute forcing if I can help it.

    For the record, I'm using it in ASP/VB.net regexp validator, I didn't realize the engine made a difference.

    Thanks again.

    So, there are a lot of subtle differences between the various regex engines out there. The most common one you'll run into is the lack of look-behind assertions. Sometimes they have it, sometimes they don't. The perl regex engine seems to have the most features with things like recursive regexes, conditionals, etc.

    Premier kakos on
  • Options
    Marty81Marty81 Registered User regular
    edited July 2008
    That being said, here's an ugly, brute force way of doing it that should work with anything. This, BTW, is incredibly ugly and I'm ashamed to even post it here, but it should work. I'll ponder this a little more and see if I can come up with something more elegant.

    *ugly regex edited out for ugliness*

    Actually, that sounds interesting and useful. Could you explain it?

    Marty81 on
  • Options
    Premier kakosPremier kakos Registered User, ClubPA regular
    edited July 2008
    Marty81 wrote: »
    That being said, here's an ugly, brute force way of doing it that should work with anything. This, BTW, is incredibly ugly and I'm ashamed to even post it here, but it should work. I'll ponder this a little more and see if I can come up with something more elegant.

    *ugly regex edited out for ugliness*

    Actually, that sounds interesting and useful. Could you explain it?

    Explain my ugly regex? It was literally just an a bunch of alternations enumerating pretty much every possibility. So (\d[a-zA-Z0-9]{4,9}|[a-zA-Z0-9]\d[a-zA-Z0-9]{3,8}|[a-zA-Z0-9]{2}\d[a-zA-Z0-9]{2,7}|...|[a-zA-Z0-9]{9}\d)

    Premier kakos on
  • Options
    The Green Eyed MonsterThe Green Eyed Monster i blame hip hop Registered User regular
    edited July 2008
    Dump her.

    The Green Eyed Monster on
  • Options
    JerryJerry Registered User regular
    edited July 2008
    Why not use 2 regular expressions?

    This regular expression validates the general content + length: [a-zA-Z0-9]{5,10}
    This regular expression checks the general content and at least one digit: [a-zA-Z0-9]*\d[a-zA-Z0-9]*

    Both pass = valid
    1st fails = Character string too long
    2nd fails = No digit
    Both fail = Invalid character

    Easy to read, provides some nice diagnostics for failure reasons (1reg ex won't tell you anything except success/failure).

    Jerry on
Sign In or Register to comment.