Java中的正则表达式。意外行为
我试图匹配大部分数字,但根据表达式后面的单词,我需要做出改变 我匹配每个数字,这些数字后面没有温度项,如°C或时间规格。 我的正则表达式如下所示:Java中的正则表达式。意外行为,java,regex,parsing,matcher,Java,Regex,Parsing,Matcher,我试图匹配大部分数字,但根据表达式后面的单词,我需要做出改变 我匹配每个数字,这些数字后面没有温度项,如°C或时间规格。 我的正则表达式如下所示: (((\d+?)(\s*)(\-)(\s*))?(\d+)(\s*))++(?!minuten|Minuten|min|Min|Stunden|stunden|std|Std|°C| °C) 0: "5 "1: "5 "2: "null"3: "null"4: &quo
(((\d+?)(\s*)(\-)(\s*))?(\d+)(\s*))++(?!minuten|Minuten|min|Min|Stunden|stunden|std|Std|°C| °C)
0: "5 "1: "5 "2: "null"3: "null"4: "null"5: "null"6: "null"7: "5"8: " "9: "null"
以下是一个例子:
虽然这种行为正是我所期望的,但Java会执行以下操作:
索引是匹配4的对应组
0: "4 "1: "4 "2: "0 - "3: "0"4: " "5: "-"6: " "7: "4"8: " "9: "°C"
你需要知道我把每个字符串分开匹配。因此,5的匹配如下所示:
(((\d+?)(\s*)(\-)(\s*))?(\d+)(\s*))++(?!minuten|Minuten|min|Min|Stunden|stunden|std|Std|°C| °C)
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());
}
}
publicstaticvoidadaptportiondetails(eliststeps,双乘法器){
String portionMatcher=“(((\\d+?)(\\s*)(\\-)(\\s*))(\\d+(\\s*))++(?!°C | Grad | minuten | min | min | studen | std | std)”;
对于(int i=0;i
希望你能说出我遗漏了什么。这似乎是Java实现中的一个bug(或功能?)。当必须从下一个索引重新进行匹配时,它似乎不会为捕获组重置捕获的文本
这个测试揭示了Java正则表达式引擎和PHP的PCRE之间的行为差异
- 正则表达式:
(\d+(\d+){1}+(?!x)
- 输入:
3434-43x7890
- Java结果:3个匹配(
,34
,78
)。第二场比赛的第二个捕获组是90
。第二个捕获组在第一场和第三场比赛中没有捕获任何内容-43
- :也是相同的3个匹配项,但第2个捕获组对所有匹配项均不捕获任何内容。对于PHP的PCRE实现,当必须重新进行匹配时,将重置捕获组的捕获文本
- 正则表达式:
a(\d+(\d+){1}+(?!x)
- 输入:
a34 a34-43x a78 a90
++
应该是{1}++
,因为您似乎希望一次修改一个数字或一个数字范围,同时使匹配具有所有格以丢弃不需要的数字
解决方法
第一个组(最外层的捕获组)捕获所有内容(一个数字或一系列数字),在找到匹配项时将始终被覆盖。因此你可以信赖它。您可以检查组1中是否存在
-
(使用包含方法)。如果有,则可以判断捕获组2包含来自当前匹配的捕获文本,并且可以使用捕获文本。如果没有,那么您可以忽略捕获组2及其嵌套捕获组中的所有捕获文本。不愉快的行为到底是什么?您能更清楚地描述它吗?您是否需要那么多的捕获组()
?因为组2到7应该为空。但在第3组中,例如字符串“0”,它是初始字符串190的最后一位。即使整场比赛是我想要的。我真的不需要所有的团体。但是我需要得到第3组和第7组,我需要用它们计算一些东西,然后把计算出的值放在指定的位置position@lugges:为什么单独放置的正则表达式与代码中的正则表达式不同?这是因为在我的原始代码中,我从不同的数组构建正则表达式,并使用print方法将其放在这里作为常数。我在最初的帖子和代码中删除了围绕°C的圆括号。还有什么我不知道的吗?谢谢。很高兴知道我理解正确,而且这种行为不符合逻辑。你对我有什么建议吗?怎样才能得到一个更适合我情况的结果