【问题标题】:How can i "merge" these two regular expression in PHP?我如何在 PHP 中“合并”这两个正则表达式?
【发布时间】:2012-09-14 17:51:17
【问题描述】:

我正在学习正则表达式,所以请放轻松!

不以_(下划线)开头并且仅包含单词字符(字母、数字和下划线本身)时,用户名被认为是有效的:

namespace Gremo\ExtraValidationBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class UsernameValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        // Violation if username starts with underscore
        if (preg_match('/^_', $value, $matches)) {
            $this->context->addViolation($constraint->message);
            return;
        }

        // Violation if username does not contain all word characters
        if (!preg_match('/^\w+$/', $value, $matches)) {
            $this->context->addViolation($constraint->message);
        }
    }
}

为了将它们合并到一个正则表达式中,我尝试了以下方法:

^_+[^\w]+$

被解读为:如果以下划线开头(最终不止一个)并且如果后面至少有一个字符是不允许的(不是字母、数字或下划线),则添加违规。例如,不适用于“_test”。

你能帮我理解我哪里错了吗?

【问题讨论】:

    标签: php regex preg-match


    【解决方案1】:

    您可以在第二个正则表达式中添加一个否定的前瞻断言:

    ^(?!_)\w+$
    

    这意味着,尝试匹配整个字符串,而不是它的任何部分。字符串不能以下划线开头,并且可以包含一个或多个单词字符。

    See it work

    【讨论】:

    • 看起来不错,但我无法得到“负前瞻”的东西。你能给我简单解释一下它是如何工作的吗?
    • 另一个问题,如果你不介意,正则表达式的哪一部分指定“尝试匹配整个字符串而不是它的任何部分”?
    【解决方案2】:

    问题是De Morgan's Law^_+[^\w]+$ 仅当它以一个或多个下划线开头时才会匹配 并且 所有 后续字符都是非单词字符。如果它以下划线开头 any 字符是非单词字符,则需要匹配。

    我认为在这种情况下,关注有效的用户名会更简单:它们以非下划线的单词字符开头,所有剩余的字符都是单词字符。换句话说,有效的用户名由^[^\W_]\w*$ 模式描述。所以,你可以写:

    if (! preg_match('/^[^\W_]\w*$/', $value, $matches)) {
    

    【讨论】:

      【解决方案3】:

      简单的解决办法是这样的:

      if (!preg_match('/^[a-zA-Z0-9]+$/', $value, $matches)) {
      

      您只想要\w 组(包括下划线)但没有下划线,所以[a-zA-Z0-9] 相当于\w 但没有下划线。

      【讨论】:

      【解决方案4】:

      当然,有很多不同的方法可以做到这一点。我可能会考虑使用类似于/^(?!_)[\w\d_]+/$ 的东西。

      [\w\d_]+ 部分与锚点(^ 和 $)相结合,基本上断言整个字符串仅由这些字符组成。 (?!_) 部分是一个否定的前瞻断言。这意味着检查下一个字符不是下划线。由于它就在 ^ 锚旁边,因此可以确保第一个字符不是下划线。

      【讨论】:

      • 仅供参考,您的正则表达式中的\d_ 是多余的; \w 已经匹配数字和下划线以及字母。
      • 确实,这是漫长的一天。
      猜你喜欢
      • 1970-01-01
      • 2021-12-30
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多