【问题标题】:PHP regex preg_match malfunctionPHP regex preg_match 故障
【发布时间】:2014-09-10 19:55:51
【问题描述】:

我正在研究注释驱动的 ACL,特别是检查语法并将给定字符串拆分为参数,如下所述。我遇到了 PHP 正则表达式解决方法的问题。

我想使用函数 preg_match 检查注解参数语法。

所需的参数格式:

foo={security module} - should pass
bar={view,delete,edit} - should pass
prelude={view, delete, edit} - should pass
typo={x} - should pass
foo={security module}prelude={view, delete, edit} - should pass
foo={security module} prelude={view, delete, edit} - should pass

所以我产生了^([a-z]+={{1}[a-z]+([,\s|,]{1}[a-z]+)*}\s*)+$ 正则表达式。

正则表达式的预期结构如下:

/ - 分隔符

^ - 单词开头

[a-z]+ - 参数名称(foo || bar || 不管)

={{1} - 恰好出现一次 ={ 序列

[a-z]+ - 声明参数的至少一个值

[,\s|,]{1} - 恰好出现一次 ",\s" 或 ","

[a-z]+ - 再次参数名称(foo || bar || 不管)

)* - 捕获的逗号块后跟值 0 - x 次

} - 右括号

\s* - 各个参数之间出现 0 到 x 次空白

)+ - 捕获整个注解参数块,因为我希望注解至少有一个参数

当它被传递到 preg_match 时,我仍然得到 0 个返回值(0 次出现的模式有效字符串)。

有人知道我在哪里犯错吗?提前致谢。

【问题讨论】:

  • 仅供参考,你永远不需要{1}——如果某事后面没有量词,它总是匹配1次。
  • [,\s|,] 并不意味着你所说的那样。它匹配,| 或空格的单个字符。您将它与(,\s|,) 混淆了,它相当于,\s?——逗号后跟空格可选。
  • 那么什么不应该通过呢?你能举出一些你没有得到预期结果的例子吗?
  • 第一行真的应该通过吗?参数之间没有逗号。

标签: php regex preg-match


【解决方案1】:

这样的?

$stuff = <<< TEST
foo={security module}
bar={view,delete,edit}
prelude={view, delete, edit}
typo={x}
foo={security module}prelude={view, delete, edit}
foo={security module}prelude={view, delete, edit}
TEST;

$regex = '/(?P<name>[a-z]+)\s*=\s*\{\s*(?P<values>[a-z\s]+(?:\s*,\s*[a-z\s]+)*)\s*\}/m';
preg_match_all($regex, $stuff, $matches, PREG_SET_ORDER);
var_dump($matches);

如果您不想在标记前后出现可选空格,则可以删除 \s*

【讨论】:

  • 我刚学会使用 \b 边界,它有助于消除子字符串的匹配。所以我会将您的解决方案编辑为: (?P\b[a-z]+\b)\s*=\s*\{\s*(?P\b[a-z\s]+\ b(?:\s*,\s*\b[a-z\s]+\b)*)\s*\}
【解决方案2】:

以下正则表达式有效:

^([a-z]+={[a-z]+((?:,|\s|,\s)[a-z]+)*}\s*)+$

我去掉了不必要的{1} 量词。我将[,\s|,] 更改为(?:,|\s|,\s),这允许参数用逗号(示例2)、空格(示例1)或逗号后跟空格(示例3)分隔。

DEMO

【讨论】:

  • 并非在所有情况下都有效(regex101.com/r/dO2nC7/4),但最重要的是,您帮助我学习了如何构造正则表达式。
【解决方案3】:

谢谢大家,你们给了我一个方向,帮助我最终克服了这个话题。

我的解决方案:

\b[a-z]+\b\s*\=\s*\{\s*\b[a-z]+\b(?:(?:\s|\.)\b[a-z]+\b\s*|(?:\s*\,\s*\b[a-z]+\b\s*)*)\}\ *

和类似的,但更严格和更易读的辅助解决方案:

\b[a-z]+\b\s*=\s*\{\b[a-z]+\b(?:(?:\ |,\ ?|\.)\b[a-z]+\b)*\}\ *

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 2012-02-15
    相关资源
    最近更新 更多