【问题标题】:Problem with a PCRE regexpPCRE 正则表达式的问题
【发布时间】:2011-08-12 03:25:02
【问题描述】:

我正在尝试创建一个可以匹配这个的正则表达式:

argument ::= define_scope [';' define_scope]*
define_scope ::= (['local'] | 'global') define_var
define_var ::= variable_name expression
variable_name ::= Name

所以,类似local varName something;;world foo bar;;local foobar bar
我试过了:

((^|;;)?(local|world) (.+?) (.+?))+

但如果我在前面的示例中使用它,我会获得这些匹配项:

local varName s
;;world foo b
;;local foobar b

所以它只需要每个匹配的最后一个单词的第一个字母。
如果我从最后一个组中删除惰性匹配,它只匹配:

local varName something;;world foo bar;;local foobar bar

所以最后一组是something;;world foo bar;;local foobar bar

解决这个问题的一些想法?

【问题讨论】:

标签: php regex pcre


【解决方案1】:

这不是常规语法,因此无法使用正则表达式解析生成的句子/单词(cs speak)。这是一个上下文无关的语法,你需要一个使用递归下降(LL-parser)的解析器。

【讨论】:

    【解决方案2】:

    正则表达式不是您工具箱中的万能工具,在这里它们还不够,但是可以通过告诉它匹配(但不是包括)分号,并删除非贪婪?

    /(^|;;)((local|world) (.+?) ([^;]+))/
    

    您的问题是. 匹配任何字符。匹配. 贪婪地在第一场比赛中吃掉了字符串的其余部分,而非贪婪地匹配第一个字符。解决方案是告诉它贪婪地匹配除分号之外的所有内容,与[^;]+。理想情况下,您应该将其限制为您实际希望出现的字符列表,而不是随意使用.

    【讨论】:

      【解决方案3】:

      这就是我需要的正则表达式:

      ((?:(local|world) )?(.*?)(?: (.+?))(?:(?<!;);(?!;)|$))+?
      

      这个可以毫无问题地解析任何有 ;; 的东西。不匹配

      谢谢大家。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-20
        • 2014-08-02
        • 1970-01-01
        • 2014-09-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多