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

如何为这些路径表达式编写正则表达式

  •  1
  • FK82  · 技术社区  · 14 年前

    我正在尝试编写一个帮助方法,它分解路径表达式并希望得到一些帮助。请考虑如下四种路径模式(圆括号表示谓词):

    1. item.sub_element.subsubelement(@key = string) ;或者,
    2. item..subsub_element(@key = string) ;或者,
    3. //subsub_element(@key = string) ;或者,
    4. item(@key = string)

    一个正则表达式看起来像什么?

    我想到的是:

     ((/{2}?[\\w+_*])(\\([_=@#\\w+\\*\\(\\)\\{\\}\\[\\]]*\\))?\\.{0,2})+
    

    我读这个是: “匹配由两个组组成的字符串的一个或多个出现项:第一组由一个或多个带可选下划线的单词和可选的双正斜杠前缀组成;第二组是可选的,至少由一个单词和所有其他可选字符组成;组后接零到两个点。”

    但是,在第四个示例上运行matcher.matches()的测试将返回false。那么,我的错误在哪里?

    有什么想法吗?

    蒂亚

    FK

    编辑:尝试 http://www.regexplanet.com/simple/index.html 我好像不知道 Matcher.matches() 以及 Matcher.find() 方法 Matcher 对象。我试图将输入字符串分解为与regex匹配的子字符串。因此我需要使用 find() 不是 matches() .

    伊迪丝2:这就是诀窍

    ([A-ZA-Z0-9_]+)\.0,2(\(.*\)?

    3 回复  |  直到 14 年前
        1
  •  3
  •   Jens    14 年前

    我想你误解了品格课。我发现在测试正则表达式时, http://gskinner.com/RegExr/ 有很大的帮助。作为正则表达式的教程,我建议 http://www.regular-expressions.info/tutorial.html .

    我不完全确定,你想如何分组。你的句子似乎暗示,你的第一组只是 item 部分 item..subsub_element(@key = string) 但是我不知道第二组应该是什么。从我从你的正则表达式推断,我将把括号前的部分分组为第一组,括号中的部分分组为第二组。如果我误解了你,你当然可以修改这个。

    我不逃避Java的表达式,所以你必须这么做。=)

    第一组应该以可选的双斜杠开始。我用 (?://)? . 在这里 ?: 意味着这部分不应该被捕获,最后一部分 ? 使前面的组成为可选的。

    接下来是包含字符和下划线的单词,按点分组。这样一个单词(带尾随点)可以表示为 [a-zA-Z_]+\.{0,2} . 这个 \w 你使用的实际上是 [a-zA-Z0-9_] 我想。它不代表一个单词,而是一个“单词字符”。

    最后一个表达式可能出现多次,因此第一个组的捕获表达式看起来像

    ((?://)?(?:[a-zA-Z_]+\.{0,2})+)
    

    对于括号中的部分,可以使用 \([^)]*\) ,这意味着一个左括号(转义,因为它有特殊意义,后面跟着任意数量的非括号(未转义,因为它在字符类中没有特殊意义),然后是一个右括号。

    结合 ^ $ 为了分别标记行首和行尾,我们得出

    ^((?://)?(?:[a-zA-Z_]+\.{0,2})+)(\([^)]*\))$
    

    如果我误解了你的要求,需要帮助,请在评论中提出。

        2
  •  3
  •   Tarski    14 年前

    你可能会发现这个网站对测试你的regex很有用 http://www.fileformat.info/tool/regex.htm .

    作为一种一般的方法,尝试从处理简单案例的regex构建regex,编写一些测试并使其通过。然后使regex更加复杂,以处理其他情况。确保它通过了原始测试和新测试。

        3
  •  0
  •   polygenelubricants    14 年前

    你的模式有很多问题:

    /{2}? 你觉得怎么样 ? 这里是什么意思?因为如果你认为 /{2} 可选,你错了。相反 ? 不愿意修改 {2} 重复。也许有点像 (?:/{2})? 就是你想要的。

    [\w+_*] 你认为 + * 这里是什么意思?因为如果你认为它们代表着重复,你就错了。这是字符类定义,并且 + * 字面意思是字符 + * . 也许你打算…事实上,我不知道你想干什么。


    解决方案尝试

    这里有一个猜测您的规范是什么的尝试:

        String PART_REGEX =
            "(word)(?:<<@(word) = (word)>>)?"
                .replace("word", "\\w+")
                .replace(" ", "\\s*")
                .replace("<<", "\\(")
                .replace(">>", "\\)");
        Pattern entirePattern = Pattern.compile(
            "(?://)?part(?:\\.{1,2}part)*"
                .replace("part", PART_REGEX)
        );
        Pattern partPattern = Pattern.compile(PART_REGEX);
    

    然后我们可以测试它如下:

        String[] tests = {
            "item.sub_element.subsubelement(@key = string)",
            "item..subsub_element(@key = string)",
            "//subsub_element(@key = string)",
            "item(@key = string)",
            "one.dot",
            "two..dots",
            "three...dots",
            "part1(@k1=v1)..part2(@k2=v2)",
            "whatisthis(@k=v1=v2)",
            "noslash",
            "/oneslash",
            "//twoslashes",
            "///threeslashes",
            "//multiple//double//slashes",
            "//multiple..double..dots",
            "..startingwithdots",
        };
        for (String test : tests) {
            System.out.println("[ " + test + " ]");
            if (entirePattern.matcher(test).matches()) {
                Matcher part = partPattern.matcher(test);
                while (part.find()) {
                    System.out.printf("  [%s](%s => %s)%n",
                        part.group(1),
                        part.group(2),
                        part.group(3)
                    );
                }
            }
        }
    

    以上印刷品:

    [ item.sub_element.subsubelement(@key = string) ]
      [item](null => null)
      [sub_element](null => null)
      [subsubelement](key => string)
    [ item..subsub_element(@key = string) ]
      [item](null => null)
      [subsub_element](key => string)
    [ //subsub_element(@key = string) ]
      [subsub_element](key => string)
    [ item(@key = string) ]
      [item](key => string)
    [ one.dot ]
      [one](null => null)
      [dot](null => null)
    [ two..dots ]
      [two](null => null)
      [dots](null => null)
    [ three...dots ]
    [ part1(@k1=v1)..part2(@k2=v2) ]
      [part1](k1 => v1)
      [part2](k2 => v2)
    [ whatisthis(@k=v1=v2) ]
    [ noslash ]
      [noslash](null => null)
    [ /oneslash ]
    [ //twoslashes ]
      [twoslashes](null => null)
    [ ///threeslashes ]
    [ //multiple//double//slashes ]
    [ //multiple..double..dots ]
      [multiple](null => null)
      [double](null => null)
      [dots](null => null)
    [ ..startingwithdots ]
    

    附件