【问题标题】:I need a PHP regular expression to validate string format of 5 digits, one comma我需要一个 PHP 正则表达式来验证 5 位数字的字符串格式,一个逗号
【发布时间】:2011-04-19 21:49:44
【问题描述】:

我在网页上有一个巨大的 PHP 输入框。此输入只能采用逗号分隔的 5 位字符串:

00100,00247,90277,97030,00657

注意最后一个没有逗号。

有没有正则表达式可以做到这一点?由于输入框非常大,可以容纳 100 多个这样的项目,我想在查询数据库之前在 PHP 服务器端验证它,避免任何 SQL 注入尝试。

仅当序列中只有 5 个数字和一个逗号时才会运行查询,最后一个除外。 顺便说一下,这些是一个州的公共供水系统 ID。

【问题讨论】:

标签: php regex expression validation


【解决方案1】:

我相信这会得到您正在寻找的结果,尽管爆炸可能是更好的选择。

/^(?:\d{5},)*\d{5}$/

这将只匹配 1 个或多个 5 位数字,这些数字以逗号分隔,没有空格。

【讨论】:

  • 所以在 PHP 中,你会使用 if(preg_match('/^(?:\\d{5},)+\\d{5}$/', $subject)) { ... }
  • 是的,没错。我没有在这台机器上安装 PHP,所以我不能确定 PHP 是否支持 ?: 非捕获组语法,但如果它不适合你的话,它也应该在没有 ?: 的情况下工作。跨度>
  • 这也匹配"00100,00247,90277,97030",但 OP 只希望匹配 5 个数字。
  • @anubhava:不,OP 想要测试用逗号分隔的 5 位数字。 “可以带 100 多个这些物品”
  • 这是他写的:Query is only run if only 5 numbers and a comma in the sequence, except for the last one. 所以我将其解释为num1,num2,num3,num4,num5
【解决方案2】:

由于这是用户提交的数据,因此您的验证应该更加灵活。如果用户不小心在一个逗号后加了一个空格怎么办?还是插入了换行符?

我知道您正在寻找正则表达式解决方案,但我建议您使用 explode 创建一个数组并将规则应用于每个元素。将它们分成元素可以在验证和存储时提供更大的灵活性:

$nums = explode(',', '00100,00247,90277,97030,00657');
foreach ($nums as $num) {
    if (!preg_match('/^\d{5}$)/', trim($num))) {
        // error!
    }
}

【讨论】:

  • 我相信这只会匹配第一个数字。
  • 你是对的。我删除了正则表达式,因为我的主要观点是建议爆炸。
【解决方案3】:

我会分解它并单独验证每个字符串:

$input = '00100,00247,90277,97030,00657';
$input_array = explode(',', $input);
$is_valid = true;

foreach ($input_array as $number) {
  if (preg_match("/\\d/", trim($number)) != strlen(trim($number))) {
    $is_valid = false;
  }
}

print($is_valid);

【讨论】:

  • 您愿意详细说明为什么选择这种方法吗?
  • 因为我鄙视正则表达式并尽量避免它,因为我无法理解它的语法。我选择直观的路线。
  • 我个人宁愿阅读一行 20 个字符的正则表达式,也不愿阅读 8 行 PHP。但这肯定需要使用正则表达式的经验。
  • 我的朋友,那是我没有的东西 ;)
  • OP 专门要求一个正则表达式。再加上说“我不使用它,因为我不明白它”可能不是走这条路的最佳理由;)
【解决方案4】:

我觉得你更需要str_getcsv:

while ($row = str_getcsv($fp)) {
    // $row is an array containing your digits
}

【讨论】:

  • 把这个改成str_getcsv,我敢打赌你不会被否决。
  • 嗯,好吧,我不会想到对文件而不是字符串进行操作会使这是一个不合适或错误的答案,但是这里有。 (谢谢,顺便说一句)
【解决方案5】:

简单。此正则表达式匹配具有一个或多个逗号分隔的 5 位数字的值:

if (preg_match('/^\d{5}(\s*,\s*\d{5})*$/', $value)) {
    // Good value
}

它也允许数字之间有空格。

【讨论】:

    【解决方案6】:

    这可能有效:

    /^\d{5}(?:,\d{5})*$/

    edit 1注意到 ridgerunner 有相同的答案,所以忽略这个。


    edit 2一些关于性能的说明。

    故障分析

    回溯失败时回馈:

    ^\d{5}(?:,\d{5})*$ 回馈,\d{5}
    ^(?:\d{5},)*\d{5}$ 回馈\d{5},

    后回溯回归地形检查:
    (回溯回馈后,支票在回馈者的右边)

    ^\d{5}(?:,\d{5})*$ 检查$
    ^(?:\d{5},)*\d{5}$ 检查\d{5}$

    获胜者:^\d{5}(?:,\d{5})*$

    NON-Backtracking 正则表达式(使用占有量词 +):

    ^\d{5}(?:,\d{5})*+$ 什么都不回,立即失败
    ^(?:\d{5},)*+\d{5}$ 什么都不回,立即失败

    基准

    使用由 50 个块组成的字符串 \d{5},
    示例字符串在 100,000 次循环中与每个正则表达式匹配。
    在绳子的末端诱导失败,移除以进行成功测试。

    成功:
    所有人都用了 1 秒来完成一次成功的运行。

    失败,回溯:
    ^\d{5}(?:,\d{5})\*$ 耗时 1.2最佳
    ^(?:\d{5},)\*\d{5}$ 耗时 1.6 秒

    失败,非回溯:
    ^\d{5}(?:,\d{5})*+$ 耗时 .9
    ^(?:\d{5},)*+\d{5}$ 耗时 .9

    结论

    回溯 - 进行最小的回溯检查
    在回溯子表达式之后。在这种情况下,
    最小的是$
    通常,将必需的表达式放在可选表达式的前面
    最佳 ^\d{5}(?:,\d{5})*$

    NON-Backtracking - 没关系。
    ^\d{5}(?:,\d{5})*+$^(?:\d{5},)*+\d{5}$

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多