簡體   English   中英

如何在 PHP 中“合並”這兩個正則表達式?

[英]How can i “merge” these two regular expression in PHP?

我正在學習正則表達式,所以請和我一起輕松!

如果用戶名不以_ (下划線)開頭且包含單詞字符(字母、數字和下划線本身),則認為用戶名有效:

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”。

你能幫我理解我錯在哪里嗎?

您可以在第二個正則表達式中添加否定前瞻斷言:

^(?!_)\w+$

現在這意味着,嘗試匹配整個字符串而不是它的任何部分。 該字符串不得以下划線開頭,並且可以包含一個或多個單詞字符。

看到它工作

問題是德摩根定律 ^_+[^\\w]+$僅當以一個或多個下划線開頭並且所有后續字符都是非單詞字符時才會匹配。 如果它以下划線開頭任何字符是非單詞字符,則需要匹配。

我認為在這種情況下,關注有效的用戶名更簡單:它們以除下划線以外的單詞字符開頭,所有剩余的字符都是單詞字符。 換句話說,有效的用戶名由模式^[^\\W_]\\w*$ 所以,你可以寫:

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

當然,有許多不同的方法可以做到這一點。 我可能會考慮使用/^(?!_)[\\w\\d_]+/$

[\\w\\d_]+部分與錨點(^ 和 $)相結合,基本上斷言整個字符串僅由這些字符組成。 (?!_) 部分是一個否定的前瞻斷言。 這意味着檢查下一個字符不是下划線。 由於它就在 ^ 錨點旁邊,因此可以確保第一個字符不是下划線。

簡單的解決方案是這樣的:

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

你只想要\\w組(包括下划線)但沒有下划線,所以[a-zA-Z0-9]等價於\\w但沒有下划線。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM