正则表达式检查字符串是否只包含字母和数字,但不是仅数字

6
我需要帮助编写一个正则表达式,用于检查字符串是否只包含字母和数字,但不能仅为数字。

有效

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

无效

* 1324
* xcvxxc%$#
* xcv123xxc%$#
* _012chars
* _test
10个回答

35
以下是我们将要使用的正则表达式组件:
  • ^$ 分别是字符串的开头和结尾锚点
  • \d 匹配数字
  • [a-zA-Z] 匹配字母
  • [a-zA-Z\d] 匹配字母或数字
  • * 表示"零次或多次"重复
有了这些,我们现在可以组成所需的正则表达式(请参见rubular.com):
^\d*[a-zA-Z][a-zA-Z\d]*$

这里是该模式的解释:
from the beginning...  till the end
|                      |
^\d*[a-zA-Z][a-zA-Z\d]*$
 \_/\______/\_________/

这三个部分包括:

  • 可能是一些数字作为前缀...
  • 但后面一定是一个字母!
  • 然后可能是一些数字和字母作为后缀

参考资料


1
(我相信@Kobi已经知道,但让我们明确一下)...这是一件好事!如果第二部分省略了+,则在没有匹配的情况下简化了回溯过程。除非第一部分匹配了所有仅由数字组成的前缀(不多也不少),否则此模式将不会进入第二部分;如果它进入第三部分,则第二部分不会回溯(因为它甚至不能重复)。如果需要进一步优化,两个重复部分也可以变成占有形式。 - polygenelubricants

6
这应该可以解决问题:
^[0-9]*[a-zA-Z]+[a-zA-Z0-9]*$

这需要至少一个字符是[a-zA-Z]


啊,我刚发完帖子就看到你的了。 - Carl
@iamserious 你是认真的吗?在我看来还好啊。 - Amarghosh
等一下,我正在使用这个网站检查:http://gskinner.com/RegExr/?2rsb2显然那里什么都没有匹配上!!现在我感到很尴尬! - iamserious
@iamserious:你需要使用多行模式。 - Gumbo
@iamserious 没有什么好尴尬的。你复制了整个字符串列表 - 逐个将字符串复制到输入区域中,它会在匹配时突出显示;或者只需勾选多行复选框;或者从正则表达式中删除 ^$ - Amarghosh

2

除了使用正则表达式,您还可以使用ctype_*()函数:

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)

但如果您需要正则表达式,您可以使用以下内容:

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

我觉得这里用 ctype 会很完美。 - iamserious

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

第一类的贪婪是否可能会消耗中间类的匹配? - Carl
@Carl:是的,如果发生这种情况,就需要回溯来找到符合整个正则表达式的匹配。 - Gumbo

1
^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$

1
@iamserious: var_dump(preg_match('/^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$/', 'ANYTHING')); // bool(true) @iamserious:var_dump(preg_match('/^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$/', 'ANYTHING')); // 布尔值(true) - BoltClock

1

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

  • (?=.*[a-z]) 正向前瞻,确保字符串中至少有一个字母(但不会消耗任何字符 - 一旦找到字母就放弃匹配的字符)。
  • [a-zA-Z0-9]+ 确保字符串仅包含字母数字字符。
  • ^$ 是字符串的开始和结束定界符。

1

就我个人而言(我讨厌正则表达式,通常觉得它们难以维护),我会分两步进行。

  1. 是否全部是字母和数字?
  2. 至少有一个字母吗?

我讨厌我的老同事留下来的代码,普遍难以维护。</发泄> 关于相关的问题,你是正确的,但如果加上一些代码,答案会显得更好。 - Kobi

0
([0-9]*[a-zA-Z]+)+

1
允许空字符串。 - MvanGeest
将最后一个星号替换为加号: ([0-9]*[a-zA-Z]+)+ - Fidi
这个匹配纯字母,不包含数字或其他字符。 - iamserious

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

翻译:从开头匹配0个或多个数字,然后匹配至少一个字母,最后匹配零个或多个字母或数字,直到结束。


-2

这应该可以工作:^([a-zA-Z0-9]*)([a-zA-Z]+)([a-zA-Z0-9]*)$ 编辑:抱歉,我把*+搞混了。


不允许只有一个字母输入,但是可以输入数字。 - unbeli
你需要交换 *+ 符号。 - BoltClock
抱歉,我弄混了 *+,现在应该可以了。 - Ties

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接