【问题标题】:What is the Regex for Only One @ Character?只有一个@字符的正则表达式是什么?
【发布时间】:2014-05-23 21:42:17
【问题描述】:

我正在寻找一个在 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");
  }
?>

【问题讨论】:

  • 这个问题似乎离题了,因为它缺乏足够的信息来诊断问题,例如尝试并告诉我们您遇到的问题,而不是简单地向社区提供要求列表。
  • 老实说,我会放弃正则表达式,而只是迭代字符串中的字符。如果您再次点击@,那么您会因错误而退出。在这种情况下,正则表达式正在使用大锤杀死苍蝇。
  • 我该怎么做@cdhowie?
  • 没有理由拒绝这个问题,因为 OP 提出了一个明确的问题,并且已经生成了代码。
  • 模式需要分隔符,例如斜杠:preg_match("/^[^@]*@[^@]*$/" ...

标签: php regex input character


【解决方案1】:

其他轻量级方法...

没有正则表达式

只需使用substr_count(见demo

<?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

使用正则表达式

编辑:刚刚看到 Sam 写了类似的东西。

如果你想使用正则表达式,你可以使用这个相当简单的正则表达式:

@

怎么样?这段代码(见demo

<?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

【讨论】:

    【解决方案2】:

    最简单的方法是使用preg_match_all() 的返回值。

    返回完整模式匹配的数量(可能为零),如果发生错误,则返回 FALSE。

    Example:

    $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';) 一样使用 access characters of Strings

    【讨论】:

    • 当我 echo $count 时,它什么也不返回。你能解释一下我如何从$password 值中得到@ 符号的数量吗?
    • @Kelsey,如果你不在 PHP >= 5.4.0,那么preg_match_all() 需要第三个参数。尝试将其更新为$count = preg_match_all('/@/', $password, $matches);
    • 当我回显$match时,它只回显Array,如何回显数字而不是单词Array?对不起,把我所有的问题都放在你身上。
    • @Kelsey,在我的例子中,$matches 将是一个匹配数组(对你来说非常没用,看到这个你会这样做print_r($matches);)。但是,preg_match_all() 的返回值(我们设置为 $count)应该等于匹配的数量。 echo $count; 应该可以工作(我认为以前没有,因为您没有 $matches,这导致它失败并返回 FALSE)。
    • 你也可以直接使用echo array_count_values(str_split($str))['@'];
    【解决方案3】:

    正如我在评论中所说,您的模式需要分隔符 /#~ 或任何您想要的(请参阅 PHP 文档并自行测试)。

    要快速确定一个字符串只包含一个@,您可以这样做:

    if (preg_match('~\A[^@]*@[^@]*\z~', $yourstr))
        echo 'There is one @';        
    else
        echo 'There is more than one @ or zero @';        
    

    【讨论】:

      【解决方案4】:

      这个正则表达式会做你想做的事:

      ^[^@]*@[^@]*$
      

      这匹配包含一个且仅一个 @ 的任何行。

      说明

      • ^ 匹配行首
      • [^@]* 匹配 @ 之前的所有内容
      • @ 匹配 @ 字符
      • [^@]* 匹配 @ 之后的所有内容
      • $ 匹配行尾

      使用

      preg_match("#^[^@]*@[^@]*$#", $passwd); //Matches $passwd if it contains only one character
      

      【讨论】:

      • 我已将我正在使用的代码添加到我的问题中。请看一下,因为我正在使用您提供的代码,但它似乎不起作用。 (它让我登录,而不是让我回到登录屏幕。)
      • 这是因为你没有正确使用 preg_match。您必须用分隔符包围正则表达式。在您的情况下,您可以使用preg_match("#^[^@]*@[^@]*$#",$_POST["password"])
      • 但我同意@Sam,你不应该在这里使用正则表达式。这会减慢您的代码速度,并增加内存使用量,但无济于事。
      【解决方案5】:

      这是您的正则表达式代码的含义:

      如果字符串中至少有一个非单词字符 ([\W]),则必须恰好有一个 at 符号 (@)。 at 符号前后可以有任意数量的任何其他字符:字母、数字、控制字符、标点符号等等。除了@之外的任何东西。

      我想知道的是,你是想说不超过一个 at-sign(即一个?) 从概念上讲,这很简单;只需摆脱第一个正则表达式检查 ("[\W]") 并将第二个正则表达式更改为:

      "^[^@]*(?:@[^@]*)?$"
      

      换句话说:

      从消耗你看到的not at-signs开始。如果您看到 @,请继续使用它,然后继续匹配剩余的 not at-signs。如果这不会让你在字符串的末尾,那只能意味着有多个@。立即放弃尝试并报告失败的匹配。

      当然,这仍然会给您留下要允许哪些其他字符的问题。我很确定[^@]* 不是您想要的。

      另外,"[\W]" 可能会按您的预期工作,但这只是偶然。你可以写成"/\W/""~\W~" "(\W)",它的工作原理是一样的。您可能希望这些方括号构成一个字符类,但它们甚至不是正则表达式的一部分;它们是正则表达式分隔符

      那你问为什么它会起作用? \W 是一个预定义的字符类,相当于[^\w]。您可以在常规字符类中使用它,但它本身就可以正常工作。

      【讨论】:

        猜你喜欢
        • 2013-08-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 2011-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多