代码之家  ›  专栏  ›  技术社区  ›  GONeale

需要有关regex上的反向引用匹配的帮助

  •  1
  • GONeale  · 技术社区  · 16 年前

    我一直在研究这个regex:
    {link=([^|{}]+)\||([^|{}]+)\||([^|{}]+)}

    我希望捕获任何非管道或括号字符,并将它们放在适当的backreference(组)中。

    如何返回以下内容:

    1. 如果测试字符串是 {link=a} 返回 a 进入第3组。
    2. 如果测试字符串是 {link=a|b} 返回 进入第2组, b 进入第3组。
    3. 如果测试字符串是 {link=a|b|c} 返回 进入第1组, 进入第2组, c 进入第3组。

    在使用上述regex的所有排列中,字符串没有正确地被选入正确的组时出现问题。我认为我有括号分组问题和/或 OR ( | )声明问题。

    事先谢谢。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Dyno Fu    16 年前

    在python中,但是语法应该是相同的,

    #!/usr/bin/python
    
    import re
    ptn = re.compile(r"""
        {link=
        (?:
          (?:([^|}]+)\|)?
          (?:([^|}]+)\|)
        )?
        ([^|}]+)
        }
        """, re.VERBOSE)
    
    l = [
        "{link=a}",
        "{link=a|b}",
        "{link=a|b|c}",
        "{link=a} {link=a|b} {link=a|b|c}",
    ]
    for s in l:
        for m in ptn.finditer(s):
            print "%s => matchs: %s => m.group(3): %s" % (
                    s, m.group(0), m.group(3))
    

    结果:

    {link=a} => matchs: {link=a} => m.group(3): a
    {link=a|b} => matchs: {link=a|b} => m.group(3): b
    {link=a|b|c} => matchs: {link=a|b|c} => m.group(3): c
    {link=a} {link=a|b} {link=a|b|c} => matchs: {link=a} => m.group(3): a
    {link=a} {link=a|b} {link=a|b|c} => matchs: {link=a|b} => m.group(3): b
    {link=a} {link=a|b} {link=a|b|c} => matchs: {link=a|b|c} => m.group(3): c
    
        2
  •  1
  •   Greg Bacon    16 年前

    如何捕获同一组中的所有匹配项?

    string[] tests = {
        "{link=a}",
        "{link=a|b}",
        "{link=a|b|c}",
    };
    
    var link = @"(?<link>[^|]+)";
    var pattern = new Regex(String.Format(@"^\{{link={0}(\|{0})*\}}$", link));
    
    foreach (var s in tests) {
        Match m = pattern.Match(s);
    
        if (!m.Success) {
            Console.WriteLine("{0}: FAIL", s);
            continue;
        }
    
        Console.Write("{0}: PASS ", s);
        foreach (var l in m.Groups["link"].Captures)
            Console.Write("[{0}]", l);
        Console.WriteLine();
    }
    

    输出:

    {link=a}: PASS [a]
    {link=a|b}: PASS [a][b]
    {link=a|b|c}: PASS [a][b][c]