正则表达式不允许使用双字符下划线


Regular Expression not allow duble underscores

我正在编写我的网站用户注册部分,我有一个简单的正则表达式如下:

if(preg_match("/^[a-z0-9_]{3,15}$/", $username)){
    // OK...
}else{
    echo "error";
    exit();
}

我不想让用户拥有这样的用户名:"___"或"x________y",这是我刚刚编写的用于替换duble下划线的函数:

function replace_repeated_underScores($string){
    $final_str = '';
    $str_len = strlen($string);
    $prev_char = '';
    for($i = 0; $i < $str_len; $i++){
        if($i > 1){
            $prev_char = $string[$i - 1];
        }
        $this_char = $string[$i];
        if($prev_char == '_' && $this_char == '_'){
        }else{
            $final_str .= $this_char;
        }
    }
    return $final_str;
}

它工作得很好,但我想知道我是否也可以用正则表达式而不是另一个函数来检查这一点。

我将不胜感激任何帮助。

只需添加负前瞻即可检查名称中是否有双下划线。

/^(?!.*__)[a-z0-9_]{3,15}$/

(?!pattern) ,称为零宽度负前瞻,将检查是否不可能从"当前位置"(当前位置是正则表达式引擎所在的位置)在字符串中找到前方的模式。它是零宽度,因为它不会在此过程中消耗文本,而不是外部部分。它是负数,因为只有在无法匹配模式的情况下,匹配才会继续(所有可能性都已用尽)。

模式是.*__的,所以它只是意味着只有当它找不到.*__的匹配时,匹配才会继续,即字符串中没有双下划线__前面。由于该组不使用文本,因此当字符串开始与模式的后半部分匹配时,您仍将位于字符串的开头 [a-z0-9_]{3,15}$ .

您已经允许大写用户名与 strtolower ,但是,仍然可以通过添加不区分大小写的标志i直接使用正则表达式进行验证:

/^(?!.*__)[a-z0-9_]{3,15}$/i