我正在寻找一个正则表达式在PHP中使用,以匹配一个字符;@
符号
例如,如果我在输入中输入:P@ssword
,则正则表达式将匹配。如果我在输入中输入P@@ssword
,正则表达式将不匹配。
这是我的PHP代码,我正在使用:
<?php
session_start();
if($_SERVER['REQUEST_METHOD'] == "POST") {
$conn=mssql_connect('d','dd','d');
mssql_select_db('d',$conn);
if(! $conn )
{
die('Could not connect: ' . mssql_get_last_message());
}
$username = ($_POST['username']);
$password = ($_POST['password']);
if (preg_match("['W]",$_POST["password"]))
{
if (!preg_match("^[^@]*@[^@]*$",$_POST["password"]))
{
header("location:logingbm.php");
} else {
}
}
if(!filter_var($_POST['username'], FILTER_VALIDATE_EMAIL))
{
if ($_POST["username"])
{
if ($_POST["password"])
{
$result = mssql_query("SELECT * FROM staffportal WHERE email='".$username."' AND
password='".$password."'");
if(mssql_num_rows($result) > 0) {
$_SESSION['staff_logged_in'] = 1;
$_SESSION['username'] = $username;
}}}} else {
if ($_POST["password"])
{
$result = mssql_query("SELECT * FROM staffportal WHERE email='".$username."' AND
password='".$password."'");
if(mssql_num_rows($result) > 0) {
$_SESSION['staff_logged_in'] = 1;
$_SESSION['username'] = $username;
}}}}
if(!isset($_SESSION['staff_logged_in'])) {
header("location:logingbm.php");
echo "<script>alert('Incorrect log-in information!');</script>";
} else {
header("location:staffportal.php");
}
?>
其他轻量级方法…
没有regex只使用substr_count
(见演示)
<?php
$str1 = "pa@s@s";
$str2 = "pa@ss";
echo (substr_count($str1,"@")==1)?"beauty'n":"abject'n"; // abject
echo (substr_count($str2,"@")==1)?"beauty'n":"abject'n"; // beauty
With regex
编辑:刚刚看到Sam写了一些类似的东西。
如果你想使用regex,你可以使用这个相当简单的regex:
@
如何?这段代码(参见演示)
<?php
$str1 = "pa@s@s";
$str2 = "pa@ss";
$regex = "~@~";
echo (preg_match_all($regex,$str1,$m)==1)?"beauty'n":"abject'n"; // abject
echo (preg_match_all($regex,$str2,$m)==1)?"beauty'n":"abject'n"; // beauty
最简单的方法是使用preg_match_all()
的返回值。
返回完整模式匹配的数目(可能为零),如果发生错误则返回FALSE。
例子:
$count = preg_match_all('/@/', $password, $matches);
非正则表达式解决方案(基于@cdhowie的评论):
$string = 'P@ssword';
$length = strlen($string);
$count = 0;
for($i = 0; $i < $length; $i++) {
if($string[$i] === '@') {
$count++;
}
}
这可以工作,因为您可以访问字符串的字符,因为您将使用普通数组($var = 'foo'; $var[0] = 'f';
)。
正如我在评论中所说,你的模式需要/
, #
, ~
或任何你想要的分隔符(请参阅PHP文档并自己测试)。
要快速确保一个字符串只包含一个@
,您可以这样做:
if (preg_match('~'A[^@]*@[^@]*'z~', $yourstr))
echo 'There is one @';
else
echo 'There is more than one @ or zero @';
这个regexp会做你想做的:
^[^@]*@[^@]*$
匹配任何包含且仅包含一个@
的行。
-
^
匹配行首 -
[^@]*
匹配@
之前的内容 -
@
匹配@字符 -
[^@]*
匹配@
之后的所有内容 -
$
匹配行尾
使用preg_match("#^[^@]*@[^@]*$#", $passwd); //Matches $passwd if it contains only one character
^
匹配行首[^@]*
匹配@
之前的内容@
匹配@字符[^@]*
匹配@
之后的所有内容$
匹配行尾preg_match("#^[^@]*@[^@]*$#", $passwd); //Matches $passwd if it contains only one character
你的regex代码的意思是:
如果字符串中至少有一个非单词字符(
['W]
),则必须有一个@号(@
)。在@号前后可以有任意数量的其他字符:字母、数字、控制字符、标点符号等等。除了@
。
我想知道的是,你是想说可以有不超过一个 at-sign(即 0 或 1 ?)这在概念上很简单;只是摆脱了第一个正则表达式检查("['W]"
),并将第二个正则表达式更改为:
"^[^@]*(?:@[^@]*)?$"
换句话说:
首先使用而不是@号。如果您看到一个
@
,继续使用它,然后继续匹配没有@号的。如果没有在字符串的末尾留下,则只能表示存在多个@
。立即放弃尝试,并报告匹配失败。
当然,这仍然给您留下了您想要允许哪些其他字符的问题。我很确定[^@]*
不是你想要的。
同样,"['W]"
可能会像你想的那样工作,但这只是偶然的。你可以把它写成"/'W/"
或者"~'W~"
"('W)"
,它都是一样的。你可能想用这些方括号来组成一个字符类,但它们甚至不是正则表达式的一部分;它们是正则表达式分隔符。
你会问,为什么它有效呢?'W
是一个预定义的字符类,相当于[^'w]
。可以在常规字符类中使用它,但它单独使用效果很好。