ngm*_*gmh 0 javascript php regex
我的网站有一个注册页面.
当用户填写表单时,他们可以通过JavaScript Regex进行实时验证,该工作正常.这通过以下方式完成:
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.";
}
Run Code Online (Sandbox Code Playgroud)
当用户通过以下方式提交表单时,将使用PHP Regex:
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.";
}
Run Code Online (Sandbox Code Playgroud)
但是,即使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.";
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您决定使用Javascript字符串中的RegExp构造函数定义模式,则它是相同的:
var re = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)([-a-zA-Z0-9!\"#$%&'()*+,./:;<=>?@\\[\\]\\\\^_`{|}~]{6,})$");
Run Code Online (Sandbox Code Playgroud)
顺便说一下,为了避免这个问题,[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.";
}
Run Code Online (Sandbox Code Playgroud)
总而言之,$Javascript和PHP之间的锚点存在细微差别.在两种语言中,它匹配字符串的结尾(默认情况下没有多行模式),但是在PHP中它也匹配行的结尾,当这一行后面跟着\n字符串结尾之前的换行符.换句话说,字符串"Password0\n"也匹配您的模式,因为$锚点在0和之间\n(在其位置\n)匹配.
为了避免这个问题,有两种可能性:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[!-~]{6,}$/D$为\z(无论模式如何,始终匹配字符串的结尾):/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[!-~]{6,}\z/