regex to check the string contains only letter and numbers but not only numbers

19,230

Solution 1

Here are the components of the regex we're going to use:

  • ^ and $ are the beginning and end of the string anchors respectively
  • \d matches a digit
  • [a-zA-Z] matches a letter
  • [a-zA-Z\d] matches a letter or a digit
  • * is "zero-or-more" repetition

With these, we can now compose the regex we need (see on rubular.com):

^\d*[a-zA-Z][a-zA-Z\d]*$

Here's an explanation of the pattern:

from the beginning...  till the end
|                      |
^\d*[a-zA-Z][a-zA-Z\d]*$
 \_/\______/\_________/

The 3 parts are:

  • Maybe some digits as a prefix...
  • But then definitely a letter!
  • And then maybe some digits and letters as a suffix

References

Solution 2

This should do it:

^[0-9]*[a-zA-Z]+[a-zA-Z0-9]*$

This requires at least one character of [a-zA-Z].

Solution 3

[a-z0-9]*[a-z]+[a-z0-9]*

Solution 4

Instead of using a regular expression, you can also use the ctype_*() functions:

var_dump(ctype_alnum('letters') && !ctype_digit('letters'));     // bool(true)
var_dump(ctype_alnum('0123chars') && !ctype_digit('0123chars')); // bool(true)
var_dump(ctype_alnum('1324') && !ctype_digit('1324'));           // bool(false)
var_dump(ctype_alnum('xcvxxc%$#') && !ctype_digit('xcvxxc%$#')); // bool(false)

But if you want a regular expression, you can use this:

var_dump(preg_match('/^[a-z0-9]*[a-z]+[a-z0-9]*$/i', $input));

Solution 5

^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$
Share:
19,230

Related videos on Youtube

Author by

ondrobaco

Updated on April 29, 2022

Comments

  • ondrobaco 8 months

    I need a help with regex which checks the string contains only letter and numbers but not only numbers

    Valid

    * letters
    * 1wret
    * 0123chars
    * chars0123
    * cha2rs
    

    Invalid

    * 1324
    * xcvxxc%$#
    * xcv123xxc%$#
    * _012chars
    * _test
    
  • MvanGeest
    MvanGeest over 12 years
    That allows the empty string.
  • Fidi over 12 years
    The replace the last asterisk with a plus-sign: ([0-9]*[a-zA-Z]+)+.
  • unbeli
    unbeli over 12 years
    does not allow single letter and does allow numbers only
  • BoltClock
    BoltClock over 12 years
    You need to switch the * and + signs.
  • Carl
    Carl over 12 years
    does the greediness of the first class potentially consume matches to the middle class?
  • Gumbo
    Gumbo over 12 years
    @Carl: Yes, it does. If that happens, backtracking will be required to find a match that fulfills the whole regular expression.
  • Carl
    Carl over 12 years
    ah, saw yours as soon as I finished posting.
  • iamserious
    iamserious over 12 years
    this matches purely alphabets.. not alphanumeric
  • BoltClock
    BoltClock over 12 years
    @iamserious: var_dump(preg_match('/^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]‌​*)$/', 'ANYTHING')); // bool(true)
  • iamserious
    iamserious over 12 years
    I think ctype will be perfect here
  • Amarghosh
    Amarghosh over 12 years
    @iamserious Are you really serious? It looks okay to me.
  • iamserious
    iamserious over 12 years
    wait a minute, I was checking using this: gskinner.com/RegExr/?2rsb2 and obviously dint match anything there!! I'm embarrassed now!
  • Gumbo
    Gumbo over 12 years
    @iamserious: You need to use the multiline mode.
  • Amarghosh
    Amarghosh over 12 years
    @iamserious Nothing to be embarrassed about. You copied the whole list of strings - copy strings one by one into the input area and it will highlight if it is a match; or just check the multiline checkbox there; or remove the ^ and $ from the regex.
  • polygenelubricants
    polygenelubricants over 12 years
    (I'm sure @Kobi already knows but let's make it explicit) ...which is a good thing! Omitting the + for the second part simplifies the backtracking process in case there's no match. This pattern will not enter the second part unless all digits-only prefix (no more, no less) is matched by the first part, and if it enters the third part, then the second part does not backtrack (since it's not even repeatable). Both repetitions can also be made possessive for further optimization if necessary.
  • Kobi
    Kobi over 12 years
    I hate the code my old colleague left behind and find it generally hard to maintain.</ranting> On a relevant note, you are correct, but the answer would have looked much better with some code.
  • Ties over 12 years
    sry i got the * and +, well now it should do it