tags:

views:

123

answers:

10

hi, 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
+2  A: 
[a-z0-9]*[a-z]+[a-z0-9]*
Vitalii Fedorenko
does the greediness of the first class potentially consume matches to the middle class?
Carl
@Carl: Yes, it does. If that happens, backtracking will be required to find a match that fulfills the whole regular expression.
Gumbo
A: 
([0-9]*[a-zA-Z]+)+
Sadat
That allows the empty string.
MvanGeest
The replace the last asterisk with a plus-sign:`([0-9]*[a-zA-Z]+)+`.
faileN
this matches purely alphabets.. not alphanumeric
iamserious
thanks you @all, i have made the change
Sadat
+1  A: 

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));
BoltClock
I think ctype will be perfect here
iamserious
A: 

this should work ^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$ EDIT sry got the * and the + messed up

does not allow single letter and does allow numbers only
unbeli
You need to switch the `*` and `+` signs.
BoltClock
It won't work...
Guillaume Lebourgeois
sry i got the `*` and `+`, well now it should do it
+1  A: 
^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$
killer_PL
this dint match ANYTHING...
iamserious
@iamserious: `var_dump(preg_match('/^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$/', 'ANYTHING')); // bool(true)`
BoltClock
+4  A: 

This should do it:

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

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

Gumbo
ah, saw yours as soon as I finished posting.
Carl
doesnt work!!!!!
iamserious
@iamserious - http://rubular.com/r/0sCHEd54Hk
Kobi
@iamserious Are you really serious? It looks okay to me.
Amarghosh
wait a minute, I was checking using this: http://gskinner.com/RegExr/?2rsb2 and obviously dint match anything there!! I'm embarrassed now!
iamserious
@iamserious: You need to use the multiline mode.
Gumbo
@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.
Amarghosh
A: 
^[0-9]*[a-zA-Z]+[0-9a-zA-Z]*$

translated: from the beginning, match 0 or more numbers, then match at least one letter, then match zero or more letters or numbers until the end.

Carl
+7  A: 

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

polygenelubricants
+1 for lack of `+`.
Kobi
(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.
polygenelubricants
+1 for actually explaining the answer rather than just giving it up.
Alex Larzelere
+1  A: 

^(?=.*[a-z])[a-zA-Z0-9]+$

  • (?=.*[a-z]) positive lookahead to make sure that there is at least one letter in the string (but doesn't consume any characters - gives up the matched characters as soon as it returns (in this case, as soon as it finds a letter)).
  • [a-zA-Z0-9]+ make sure string contains only alphanumeric characters.
  • ^ and $ are start and end of string delimiters.
Amarghosh
+1  A: 

Personally (I hate regex and find them generally to be hard to maintain), I'd do it in two steps.

  1. Is it all alphanumeric?
  2. Is there at least one letter?
Visage
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.
Kobi