gpt4 book ai didi

javascript - 正则表达式适用于 JavaScript,但不适用于 PHP

转载 作者:行者123 更新时间:2023-11-28 14:46:27 24 4
gpt4 key购买 nike

我的网站有一个注册页面。

当用户填写表单时,他们会通过 JavaScript 正则表达式进行实时验证,效果很好。这是通过以下方式完成的:

var password = document.getElementsByName("password")[0].value;
var pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)([a-zA-Z0-9!\"\#$%&\'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{6,})$/;
if(pattern.test(password)){
document.getElementById("check_password").innerHTML = "Password is valid.";
} else {
document.getElementById("check_password").innerHTML = "Password is invalid. It should have at least 6 characters, and 1 lowercase letter, uppercase letter, and number.";
}

当用户通过以下方式提交表单时,将使用 PHP 正则表达式:

if(!preg_match("/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)([a-zA-Z0-9!\"\#$%&\'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{6,})$/", $_POST["password"])){
$error = "Password is invalid. It should have at least 6 characters, and 1 lowercase letter, uppercase letter, and number.";
}

但是,即使 JavaScript 不抛出错误,PHP 也会不断抛出错误。两个正则表达式是相同的,并且已经在 PHP 设置和 JavaScript 设置中进行了测试。然而它可以在 JavaScript 中运行,但不能在 PHP 中运行!

为什么它在 PHP 中不起作用,我该如何解决这个问题?

最佳答案

问题出在反斜杠上。要计算 php 正则表达式字符串中的文字反斜杠,您需要使用 4 个反斜杠(您需要为字符串转义一次,为正则表达式转义一次,因为它也是正则表达式特殊字符):

if(!preg_match("/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)([a-zA-Z0-9!\"\#$%&\'()*+,\-.\/:;<=>?@\[\\\\\]^_`{|}~]{6,})$/", $_POST["password"])){
$error = "Password is invalid. It should have at least 6 characters, and 1 lowercase letter, uppercase letter, and number.";
}

请注意,如果您决定使用 JavaScript 字符串中的 RegExp 构造函数定义模式,情况是一样的:

var re = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)([-a-zA-Z0-9!\"#$%&'()*+,./:;<=>?@\\[\\]\\\\^_`{|}~]{6,})$");

顺便说一句,为了避免这个问题,字符类 [a-zA-Z0-9!\"\#$%&\'()*+,\-.\/:;<=>?@\[\\\\\]^_``{|}~]可以缩短为[!-~] 。另外,您不需要捕获组:

if(!preg_match("/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[!-~]{6,}$/", $_POST["password"])){
$error = "Password is invalid. It should have at least 6 characters, and 1 lowercase letter, uppercase letter, and number.";
}

最后,与 anchor $ 存在细微差别介于 JavaScript 和 PHP 之间。在两种语言中,它匹配字符串的结尾(默认情况下没有多行模式),但在 PHP 中,当后面跟着换行符 \n 时,它也匹配行的结尾。就在字符串末尾之前。换句话说,字符串 "Password0\n"也匹配您的模式,因为 $ 0之间的锚定匹配和\n (在 \n 的位置)。

为了避免这个问题,有两种可能性:

  • 您可以使用D modifier (PCRE_DOLLAR_ENDONLY) :
    /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[!-~]{6,}$/D
  • 或更改 $\z (无论模式如何,总是且仅匹配字符串的末尾):
    /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[!-~]{6,}\z/

关于javascript - 正则表达式适用于 JavaScript,但不适用于 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46244576/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com