正则表达式可以提取字符串中嵌入的值,如先前在同一字符串中定义的变量模板所标识的那样?或者这在Java中处理得更好?
例如:“2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]” 变量模板是遇到的第一个带方括号的字符串,例如 [F12],所需的变量是在该模板的后续实例中找到,例如“OL”和“3”。
正则表达式可以提取字符串中嵌入的值,如先前在同一字符串中定义的变量模板所标识的那样?或者这在Java中处理得更好?
例如:“2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]” 变量模板是遇到的第一个带方括号的字符串,例如 [F12],所需的变量是在该模板的后续实例中找到,例如“OL”和“3”。
由于您提到了 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));
}