代码之家  ›  专栏  ›  技术社区  ›  Richard Walton

正则表达式问题

  •  0
  • Richard Walton  · 技术社区  · 15 年前

    嘿,伙计们-我正在努力创建一个正则表达式来匹配以下内容:

    {TextOrNumber{MoreTextOrNumber}} 
    

    注意打开/关闭的匹配号码。这是可能的吗?

    多谢。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Konrad Rudolph    15 年前

    注意打开/关闭的匹配号码。这是可能的吗?

    但从历史上看,现代正则表达式实际上不是 有规律的 有些允许这样的构造:

    \{TextOrNumber(?R)?\}
    

    (?R) recursively inserts the pattern again .注意,目前还没有多少regex引擎支持这一点。

        2
  •  0
  •   brianegge    15 年前

    如果需要执行任意数量的大括号,可以使用解析器生成器,或者在嵌套函数内创建regex。下面是Ruby中递归regex的一个例子。

    def parse(s)
      if s =~ /^\{([A-Za-z0-9]*)({.*})?\}$/ then
        puts $1
        parse($2)
      end
    end
    
    parse("{foo{bar{baz}}}")
    
        3
  •  0
  •   Etan bbum    15 年前

    如果没有可用的递归扩展,那么使用1 regex是不可能的。你必须多次匹配像下面这样的正则表达式

    /\{[a-z0-9]+([a-z0-9\{\}]+)?\}/i
    

    捕获“moretextornumber”并让它再次匹配,直到您完成或失败为止。

        4
  •  0
  •   Yaakov Belch    15 年前

    不容易,但可能

    正式地说,正则表达式不是为解析嵌套的成对括号而设计的——如果您尝试这样做,就会遇到各种各样的问题。还有其他一些工具(如解析器生成器,例如yacc或bison)是为这种结构设计的,可以很好地处理它们。但这是可以做到的---如果你做得对,它甚至可能比一个包含所有支持代码的yacc语法更简单,可以解决yacc的问题。

    以下是一些提示:

    首先,如果您有一些永远不会出现在输入中的字符,我的建议最有效。通常,像“01”和“02”这样的字符不应该出现,所以你可以这样做。

    s/[\01\02]/ /g; 
    

    确保他们不在那里。否则,您可能希望逃离它们(例如,将它们转换成类似于% 0和% 1的文本),表达式如下

    s/([\01\02%])/"%".ord($1)/ge;
    

    注意,我还转义了转义符“%”。

    现在,我建议分析括号 从里到外 :替换任何子字符串“文本”,其中“文本”表示 包含一个占位符“\01$number\2”的任何括号,并将包含的文本存储在$array[$number]中:

    $number=1;
    while (s/\{([^{}]*)\}/"\01$number\02"/e) { $array[$number]=$1; $number++; }
    $array[0]=$_;  # $array[0] corresponds to your input
    

    作为最后一步,您可能希望处理@array中的每个元素,以拉出并处理“\01$number\02”标记。这很容易,因为它们不再嵌套。

    我很乐意在一些解析器中使用这个想法(包括分离匹配的括号类型,如“()[]等)。

    但是在您走上这条路之前,请确保在更简单的应用程序中使用了正则表达式:您 遇到许多小问题,你需要经验来解决它们(而不是把一个小问题变成两个小问题等)。