1

正则表达式可以提取字符串中嵌入的值,如先前在同一字符串中定义的变量模板所标识的那样?或者这在Java中处理得更好?

例如:“2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]” 变量模板是遇到的第一个带方括号的字符串,例如 [F12],所需的变量是在该模板的后续实例中找到,例如“OL”和“3”。

4

1 回答 1

0

由于您提到了 Java,我假设您使用的是 Java 实现Pattern

Java 的 Pattern 支持所谓的反向引用,它可用于匹配与先前捕获组匹配的相同值。

不幸的是,您无法从单个捕获组中提取多个值,因此如果您想使用单个模式执行此操作,则必须对要匹配的模板数量进行硬编码。

对于一个变量,它可能如下所示:

\[(.*?)\].*?\[\1#(.*?)\]
  ^^^^^          ^^^^^ variable
 template     ^^ back reference to whatever template matched

您可以通过将它们包装在可选的非捕获组中来添加更多可选匹配,如下所示:

\[(.*?)\].*?\[\1#(.*?)\](?:.*?\[\1#(.*?)\])?(?:.*?\[\1#(.*?)\])?
                        ^ optional group    ^ another one

这将匹配最多三个变量:

    String s = "2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]";
    String pattern = "\\[(.*?)\\].*?\\[\\1#(.*?)\\](?:.*?\\[\\1#(.*?)\\])?(?:.*?\\[\\1#(.*?)\\])?";
    Matcher matcher = Pattern.compile(pattern).matcher(s);
    if (matcher.find()) {
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.println(matcher.group(i));
        }
    }

    // prints F12, OL, 3, null

但是,如果您需要匹配任意数量的变量,则必须在第一遍中提取模板,然后将其嵌入到第二个模式中:

    // compile once and store in a static variable
    Pattern templatePattern = Pattern.compile("\\[(.*?)\\]");

    String s = "2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]";

    Matcher templateMatcher = templatePattern.matcher(s);

    if (!templateMatcher.find()) {
        return;
    }

    String template = templateMatcher.group(1);
    Pattern variablePattern = Pattern.compile("\\[" + Pattern.quote(template) + "#(.*?)\\]");

    Matcher variableMatcher = variablePattern.matcher(s);
    while (variableMatcher.find()) {
        System.out.println(variableMatcher.group(1));
    }
于 2012-07-06T19:33:11.110 回答