检查字符串是否包含数字和字母

40
我想检测一个字符串是否同时包含数字和字母。
例如:
- 给定字符串 PncC1KECj4pPVW,它会被写入文本文件,因为它同时包含数字和字母。 - 给定字符串 qdEQ,它不会被写入文本文件,因为它只包含字母。
有什么方法可以做到这一点吗?
我尝试使用
$string = PREG_REPLACE("/[^0-9a-zA-Z]/i", '', $buffer);

但是它没有起作用。

任何帮助都将不胜感激。


5
带有/i修饰符的[a-zA-Z]有点像一种用词重复。 - Mark Baker
@MarkBaker 当你想要确保它不区分大小写时 :) - jb.
2
字符串中允许包含非字母数字字符吗? - Jonathan M
11个回答

59

看起来最简单的方法就是用两个正则表达式来实现。

if (preg_match('/[A-Za-z]/', $myString) && preg_match('/[0-9]/', $myString))
{
    echo 'Contains at least one letter and one number';
}

我认为另一种方法是如下所示。它表示“首先是一个字母,然后在某个时候是一个数字(或反之亦然)”。但我认为上面那个更易读。

if (preg_match('/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/', $myString))
{
    echo 'Contains at least one letter and one number';
}

我没有给你的回答点踩,但是你的第一和第二个解决方案会匹配 "000 aaaa 111" 这样的字符串,而我认为这应该被视为无效(只有像 "000aaaa111" 这样的字符串才是有效的,字符串中不应包含除字母数字以外的其他字符)- 然而,原帖并没有指定 "000 aaaa 111" 应该被视为无效,但是所给出的示例表明了这种行为。 - Maxime Pacary
@FrostyZ,你说得很对,但问题并没有说它不应该包含其他字符。我按照问题所写的回答了它。 - jb.
@FrostyZ,楼主没有规定其他字符不允许出现。我理解为是可以的。除非另有规定,否则它们应该是允许的。你不能仅仅根据一个例子来判断,否则你也得说数字必须在字母后面。 - Jonathan M
@Jonathan,向邓肯询问细节是正确的做法。我在这里只是猜测。 - Maxime Pacary
@FrostyZ 我同意。如果没有非字母数字的要求,那你的代码会很好用。不过你应该加上大写字母。 - jb.

39

26
@邓肯,只有在字母出现在数字之前时才有效。对于 9877abc 将无效。 - Jonathan M
1
是的,@jb和JonathanM都是正确的。我点赞了她的评论。我更喜欢jb下面的第一个解决方案(第三个答案)。 - Mohammad Naji
9
如果你因为别人指出你的答案有缺陷而更喜欢别人的答案,那么为什么不改进自己的答案呢?特别是考虑到它是被接受的答案。 - James
9
哇,这个答案太糟糕了。 - Robo Robok

8

这个工作干净利落:

$myString="abc123";
if( preg_match('([a-zA-Z].*[0-9]|[0-9].*[a-zA-Z])', $myString) ) 
{ 
    echo('Has numbers and letters.');
} else {
    echo("no");
}

要看它的实际效果,复制并粘贴到这里:http://phptester.net/index.php?lang=en

这适用于字母-数字或数字-字母的情况。但是,它允许其他字符(因为您在帖子中没有说要排除它们)。 - Jonathan M
更新了非字母数字字符。 - Jonathan M
你的非字母数字版本让我感到缺失。如果我想在中间加入一个数字怎么办? - jb.
它“有效”是因为它不会消耗整个字符串。ab!c1返回true,因为它只匹配c1。虽然我确实喜欢那个phptester网站,所以谢谢你向我展示它。 - jb.
@jb。好的发现。如果需要的话,还需要更多的琢磨。已移除。 - Jonathan M

7
我的唯一问题是是否必须只使用一个正则表达式。我会选择两个或三个(因为你必须构建一个稍微复杂的正则表达式来一次性完成它)。
假设您需要:
至少一个大写字母[A-Z]
至少一个小写字母[a-z]
至少一个数字\d
密码长度至少为7个字符
最简单和最有效的解决方案:
if( preg_match( '~[A-Z]~', $password) &&
    preg_match( '~[a-z]~', $password) &&
    preg_match( '~\d~', $password) &&
    (strlen( $password) > 6)){
    echo "Good password";
} else {
    echo "Not so much";
}

否则,在一个正则表达式中,你将不得不考虑几个选项:
  • [a-z][A-Z]+\d
  • [a-z]\d+[A-Z]
  • [A-Z][a-z]+\d
  • [A-Z]\d+[a-z]
  • \d[a-z]+[A-Z]
  • \d[A-Z]+[a-z]
将它们合并成一个难以理解的大型"ored"正则表达式,如下所示:
~([a-z][A-Z]+\d|[a-z]\d+[A-Z]|[A-Z][a-z]+\d|[A-Z]\d+[a-z]|\d[a-z]+[A-Z]|\d[A-Z]+[a-z])~

当需要检查大小写时,你可以使用以下方法:
preg_match( '~([a-z][A-Z]|[a-z][A-Z])~');

我建议使用第一个解决方案。第二个解决方案对我来说看起来效率低下且难以阅读。仍需手动检查长度。


4

PHP中有一个内置的函数可以实现此功能。它被称为ctype_alnum

if(!ctype_alnum($string)) {
  return $error;
}
// Continue on your way...

3
这是一个很好的功能。然而,它并没有回答 OP 的问题,因为它只检查字符串是否包含字母或数字,而没有验证字符串是否包含两者都有。 - butlerblog
1
这个答案显然是错误的。我讨厌看到错误的答案被投赞成票。https://3v4l.org/MNIt8 - mickmackusa
误导性的答案。它只检查所有字符是否为拉丁字母或数字。如果字符串(例如密码)还包含一些特殊字符呢?或者来自非拉丁字母表的字符呢? - Aleksey Kuznetsov

0
如果你只想匹配字母和数字字符(也就是说,只要字符串中有空格或特殊字符等其他内容,就将其视为无效),那么这个方法应该可以解决问题。
否则,只需删除第一个 preg_match() 即可。
function myTest($string)
{
  echo "test '".$string."': "
    . intval(preg_match('/^[a-z\d]+$/i', $string) // has only chars & digits
        && preg_match('/[a-z]/i', $string)        // has at least one char
        && preg_match('/\d/', $string))          // has at least one digit
    . "\n";
}

myTest('aAa'); // => 0
myTest('111'); // => 0
myTest('aAa111bbb'); // => 1
myTest('111aAabbb'); // => 1
myTest('aAabbb111'); // => 1
myTest('111bBb222'); // => 1
myTest('111 bBb 222'); // => 0
myTest('$$$$'); // => 0

0
如果您需要支持多种语言,从PHP 5.1开始,为以下字符类型添加了额外的转义序列(在此处列出)
以下函数利用此功能,允许您检查多种字母表中的字母和数字:
检查字符串中是否存在任何字母:
function has_letter($x){
    if (preg_match("/[\p{L}]/u",$x)) {
            return true;
    }
    return false;
}

检查字符串是否包含任何数字

function has_number($x) {
    if (preg_match("/[\p{N}]/u",$x)) {
        return true;
    }
    return false; 
}

使用方法

$string = '123اختبا';
has_letter($string); // true


$string = '೪౨౨'; 
has_number($string); // true

按照要求一起返回

$string='I am 28';
if (has_letter($string)&&has_number($string)){
    // true
}

$string='I am ౨೩೫';
if (has_letter($string)&&has_number($string)){
    // true
}

$string='Привет, друг, как ты?';
has_number($string); // false - this Russian text doesn't contain a number

字符类(方括号)不是必需的。 - mickmackusa

0

用于检查字符串是否包含数字的代码!!

function ContainsNumbers($String){
    return preg_match('/\\d/', $String) > 0;
}

0

这些答案有些不靠谱...我喜欢最短、最干净的解决方案。这是我基本的库,我在制作游戏时更新和改进了20年。是的,PHP有一些内置函数来检查其中的一些内容,但我喜欢简单、简短的单词函数。

以下是两个示例,都使用我的函数执行完全相同的操作。

$fullname = abcSpc($_POST['fullname']) ? $_POST['fullname'] : false;
// Same As
if(abcSpc($_POST['fullname']){ $fullname=$_POST['fullname']; } else { $fullname=false; }

我的图书馆

// BASIC FUNCTIONS, JAYY's LIBRARY
function abc ($input){ return preg_match('/^[A-Z]+$/i', $input); }
function abcSpc ($input){ return preg_match('/^[a-z][a-z\ ]*$/i', $input); }
function abcNum ($input){ return preg_match('/^[A-Z0-9]+$/i', $input); }
function abcNumSpc ($input){ return preg_match('/^[A-Z0-9\ ]+$/i', $input); }
function abcNumU ($input){ return preg_match('/^[A-Z0-9_-]+$/i', $input); }
function abcNumD ($input){ return preg_match('/^[A-Z0-9-]+$/i', $input); }
function num ($input){ if(strlen($input) > 24){ $input=0; }if(!preg_match('/^[0-9]+$/', $input)){ $input=0; } return $input; }
function numU ($input){ return preg_match('/^[0-9_-]+$/i', $input); }
function is_odd($num){ return($num & 1); }
function email ($input){ return filter_var($input, FILTER_VALIDATE_EMAIL); }
function is_url($input){ return preg_match('/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}'.'((:[0-9]{1,5})?\/.*)?$/i',$input); }
function is_uri ($input){ return preg_match('/^[a-z0-9-]+$/i', $input); }

U = 下划线,D = 破折号...

注意:num() 检查字符串长度,因为五到十年前的某个玩家发现,如果输入一个非常大的数字,它会破坏 num() 并产生一个不仅仅是数字的字符串。你可以删除它或从我的经验中学习。那个玩家最终获得了数百万免费的战争单位,摧毁了游戏的整个回合。找出他做了什么并不好玩。

我希望这能帮助到某些人。这是我的第一篇帖子,我通常不参与讨论。我只是喜欢阅读和从别人的错误中学习。如果你们看到改进的空间,请随意为我改进我的库。


[0-9] 更简单的写法是 \d$input = 0; 很奇怪,应该改为 return false;。在 /^[0-9_-]+$/i 中没有需要忽略大小写的内容。字符类中的 . 和空格不需要转义以便被当做字面量处理。(http|https) 更简单的写法是 https?($num & 1) 不需要括号。 - mickmackusa

0

给你。下面的函数检查并返回 TRUE,如果字符串包含字母字符(不仅来自拉丁字母表,还支持西里尔字母、希腊字母、希伯来字母和其他字符),并且它包含数字字符(数字)。函数需要同时存在数字和非数字(但是字母)字符才能返回 TRUE。

function is_good_string($s) {
    return preg_match('/\w/u', $s, $dummy) && // any alphabetic unicode character
           preg_match('/\d/', $s, $dummy) && // AND digit
           preg_match('/\D/', $s, $dummy); // AND non-digit
}

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