我正在尝试匹配大多数数字,但根据表达式的字词,我需要有所作为。
我匹配每个未跟随温度条件的数字,如°C或时间规格。 我的正则表达式如下所示:
(((\d+?)(\s*)(\-)(\s*))?(\d+)(\s*))++(?!minuten|Minuten|min|Min|Stunden|stunden|std|Std|°C| °C)
以下是一个示例:http://regexr.com?33jeg
虽然这个行为是我所期望的Java所做的以下: 索引是匹配4的相应组
0: "4 "1: "4 "2: "0 - "3: "0"4: " "5: "-"6: " "7: "4"8: " "9: "°C"
您需要知道我将每个字符串分开匹配。所以5的匹配看起来像这样:
0: "5 "1: "5 "2: "null"3: "null"4: "null"5: "null"6: "null"7: "5"8: " "9: "null"
这就像其他匹配一样。这种不愉快的行为只有在匹配前的字符串
中有“ - ”时才会出现我的Java代码如下:
public static void adaptPortionDetails(EList<Step> steps, double multiplicator){
String portionMatcher = "(((\\d+?)(\\s*)(\\-)(\\s*))?(\\d+)(\\s*))++(?!°C|Grad|minuten|Minuten|min|Min|Stunden|stunden|std|Std)";
for (int i = 0; i < steps.size(); i++) {
Matcher matcher = Pattern.compile(portionMatcher).matcher(
steps.get(i).getDescription());
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
printGroups(matcher);
String newValue1Str;
if (matcher.group(3) == null){
newValue1Str = "";
System.out.println("test");
}else{
double newValue1 = Integer.parseInt(matcher.group(3)) * multiplicator;
newValue1Str = Fraction.getFraction(newValue1).toProperString();
}
double newValue2 = Integer.parseInt(matcher.group(7)) * multiplicator;
String newValue2Str = Fraction.getFraction(newValue2).toProperString();
matcher.appendReplacement(sb, newValue1Str + "$4$5$6" + newValue2Str + "$8");
}
matcher.appendTail(sb);
steps.get(i).setDescription(sb.toString());
}
}
希望你能说出我所缺少的东西。
答案 0 :(得分:0)
这似乎是Java实现中的一个错误(或功能?)。当必须从下一个索引重做匹配时,它似乎不会重置捕获组的捕获文本。
此测试揭示了Java正则表达式引擎与PHP的PCRE之间的行为差异。
(\d+(-\d+)?){1}+(?!x)
34 34-43x 78 90
34
,78
,90
)。第二场比赛的第二场比赛是-43
。第二个捕获组没有捕获第一和第三场比赛的任何内容。这是在JRE 6 Update 37和JRE 7 Update 11上测试的。
相同的结果,只是为了证明在重新匹配时不重置捕获文本的重点:
a(\d+(-\d+)?){1}+(?!x)
a34 a34-43x a78 a90
关于你的正则表达式的一些评论
我认为++
应该是{1}+
,因为您似乎希望一次修改一个数字或一个数字范围,同时使匹配占有欲以丢弃不需要的数字。
解决方法强>
当找到匹配项时,将始终覆盖捕获所有内容(一个数字或一个数字范围)的第一个组(最外面的捕获组)。因此,你可以依靠它。您可以检查组1中是否存在-
(使用contains
方法)。如果有,则可以告诉捕获组2包含当前匹配中捕获的文本,您可以使用捕获的文本。如果没有,则可以忽略捕获组2及其嵌套捕获组中捕获的所有文本。