【问题标题】:PHP regex check length without using lookaheadPHP正则表达式检查长度而不使用前瞻
【发布时间】:2021-08-17 19:41:15
【问题描述】:

查看了另外 2 个与正则表达式相关的问题,这两个问题都远远超出了我在 X'D 方面需要的帮助。

<?php 

$userName = trim($_POST['username']);
if(preg_match("/^[a-zA-Z].*(?(\d)).{8,}$/", $userName)){
    
    echo 'woot!';

我不太确定它为什么会失败。我知道它检查第一个字符必须是 alpha,然后去更多 * 但最后检查它是否是一个数字?(\ d)...但是为什么不检查我的 $userName 的长度是否为 8 或更多?

如果我这样做

... *(?(\d){8,} 

它会查找 8 位或更多位,而不是字符串本身是否为 8 位或更多位。

用户必须:以字母开头,只能以数字结尾,并且只能包含 alphaNumeric,必须至少为 8 个字符,并且大小写相同。也就是说我需要在我的正则表达式末尾添加一个 i。


因此,没有办法将其转换为正则表达式的形式,向前看? ^...$.{8,} 不行吗?

【问题讨论】:

  • 请清楚地告诉我们用户名的规则是什么?很明显,它必须以字母开头,并且在稍后的某个时间点也有一个数字。其余的不清楚。
  • 用户必须:以字母开头,只能以数字结尾,并且只能包含字母数字,必须至少为8个字符,并且大小写相同。也就是说我需要在我的正则表达式末尾添加一个 i。

标签: php regex validation preg-match


【解决方案1】:

用户必须:以字母开头,只能以数字结尾,并且只能包含 alphaNumeric,必须至少为 8 个字符,并且大小写相同。

你可以使用这个简单的正则表达式来满足这个要求:

^[A-Za-z][a-zA-Z\d]{6,}\d$

正则表达式详细信息:

  • ^:开始
  • [A-Za-z]: 匹配开头的 ASCII 字母
  • [a-zA-Z\d]{6,}:匹配一个字母或数字 6 次或更多次
  • \d:匹配结束前的一个数字
  • $:结束

RegEx Demo

【讨论】:

  • 您可以将其简化为 ^[A-Z][A-Z\d]{6,}\d$ 并在不区分大小写模式下使用它。
  • 是的,我们可以像这样使用/i。我想我只是想在正则表达式中给出完整的解决方案,只是为了便于阅读,否则 /^[A-Z][A-Z\d]{6,}\d$/gmi 会更短。
  • @Coding_Noob:这个解决方案对你有用吗?
【解决方案2】:

使用以下正则表达式模式:

^(?=.{8,}$)[A-Z][A-Z0-9]*[0-9]+$

示例脚本:

$userName = trim($_POST['username']);
if (preg_match("/^(?=.{8,}$)[A-Z][A-Z0-9]*[0-9]+$/i", $userName)) {
    echo "MATCH";
}

值得注意的是,正则表达式模式在模式的开头使用(?=.{8,}$)。这是一个积极的lookahead,它断言匹配至少有 8 个字符。

如果您不想使用前瞻,您可以使用strlen() 明确检查用户名长度:

$userName = trim($_POST['username']);
if (preg_match("/^[A-Z][A-Z0-9]*[0-9]+$/i", $userName) &&
    strlen($userName) >= 8) {
    echo "MATCH";
}

【讨论】:

  • 是的,我看到了一些关于前瞻的事情;有没有办法做到这一点?我们在我所参加的课程中没有涉及到这一点,我真的很想了解为什么它不能像我的正则表达式那样工作;或者它是如何工作的:)?
  • 使用strlen()查看字符数?
  • 因此没有办法将其转换为正则表达式,然后向前看? ^...$.{8,} 不起作用?
  • (你可以省略[0-9]+之后的最后一个+作为字符类,然后它也匹配数字)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多