Java中的正则表达式,一行中多次使用同一正则表达式

Java中的正则表达式,一行中多次使用同一正则表达式,java,regex,duplicate-removal,Java,Regex,Duplicate Removal,我想分析一行中12个(通常)不同浮动的字符串(前面有一些不相关的文本,标记一个字段),并希望它们都在自己的捕获组中结束,以便从匹配器一次收集一个。我注意到,通过写以下内容,我取得了成功: Pattern lastYearIncomePattern = Pattern.compile("(.+\\{\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]

我想分析一行中12个(通常)不同浮动的字符串(前面有一些不相关的文本,标记一个字段),并希望它们都在自己的捕获组中结束,以便从匹配器一次收集一个。我注意到,通过写以下内容,我取得了成功:

Pattern lastYearIncomePattern = Pattern.compile("(.+\\{\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)([0-9]{1,2}\\.[0-9]{3}\\s)");
这是大量重复的代码。部分
([0-9]{1,2}\\.[0-9]{3}\\s)
将出现12次

有没有更好的办法?我曾经考虑过为自己定义这个字符串,然后通过一些循环和StringBuilder将它添加到正则表达式中,但这一切似乎都太过分了。显然,反向引用也不起作用,因为12个值是不同的

我的第一种方法是编写
([0-9]{1,2}\\.[0-9]{3}\\s){12}
,但这将把所有12个浮点放在一个长字符串中,这不是我想要的,因为我需要另一种模式来逐个挑选浮点,然后首选重复的frenzy解决方案


谢谢,您可以编写regexp以匹配单个浮点,然后使用来迭代出现的情况。

您可以编写regexp以匹配单个浮点,然后使用来迭代出现的情况。

Pattern lastYearIncomePattern = java.util.regex.Pattern.compile("(.+\\{\\s)(([0-9]{1,2}\\.[0-9]{3}\\s){12})");

Matcher matcher = lastYearIncomePattern.matcher(input);
boolean found =matcher.find();
if(found){
  String[] values= matcher.group(2).split("\\s");
}
它起作用了。我很想看看是否能像你希望的那样在一次操作中完成。

这个怎么样:

Pattern lastYearIncomePattern = java.util.regex.Pattern.compile("(.+\\{\\s)(([0-9]{1,2}\\.[0-9]{3}\\s){12})");

Matcher matcher = lastYearIncomePattern.matcher(input);
boolean found =matcher.find();
if(found){
  String[] values= matcher.group(2).split("\\s");
}


它起作用了。我很想看看是否可以像您希望的那样在一次操作中完成。

+1,但是在调用
group()
之前,您应该检查
find()返回的值。是的,这非常有效。我绝对认为它比我自己的解决方案更好。但这并不是我想要的完美选择(一个接受不同价值观的反向参考)。@Mats_SX:你的完美选择并不存在。在Perl中,您可以在匹配过程中将每个捕获分配给它自己的变量,但这意味着使用12个捕获组,就像您所做的那样。在.NET中,您可以使用一个捕获组重复12次,它将保留所有中间捕获,但您仍然必须通过CaptureCollection才能访问它们;这种
split()。如果你认为值得努力,你可以将结果封装在一个专用类中。是的,我将继续使用这种方法。谢谢大家的帮助+1,但是在调用
group()
之前,应该检查
find()
返回的值。是的,这非常有效。我绝对认为它比我自己的解决方案更好。但这并不是我想要的完美选择(一个接受不同价值观的反向参考)。@Mats_SX:你的完美选择并不存在。在Perl中,您可以在匹配过程中将每个捕获分配给它自己的变量,但这意味着使用12个捕获组,就像您所做的那样。在.NET中,您可以使用一个捕获组重复12次,它将保留所有中间捕获,但您仍然必须通过CaptureCollection才能访问它们;这种
split()。如果你认为值得努力,你可以将结果封装在一个专用类中。是的,我将继续使用这种方法。谢谢大家的帮助!这确实有效,但这意味着我必须使用一个常量来增加我想要读取的每个新浮点的索引,因为该操作会为每个调用重置匹配器,就像(int I=1;I<13;++I){if(matcher.find(C+5*I)){String value=matcher.group();}
那样,我不愿意这样使用常量。或者我在如何使用该操作方面弄错了?您可以使用不带参数的find()方法,或者使用Matcher.end()返回的值作为参数。您可能需要一个while循环(“while(m.find())”)。这确实有效,但这意味着我必须使用一个常量来增加我要读取的每个新浮点的索引,因为该操作会为每个调用重置匹配器,就像(int I=1;I<13;++I){if(matcher.find(C+5*I)){String value=matcher.group();}
我不愿意这样使用常量。或者我在如何使用该操作方面弄错了?您可以使用不带参数的find()方法,或者使用Matcher.end()返回的值作为参数。您可能需要一个while循环(“while(m.find())”)。您是否正在尝试编写自己的解析器?是的,我有一个项目将为eu2保存文件构建一些内部结构,然后对其进行修改并尝试再次将其写入文件。基本上,我想做的是将某些值随机化,为MP游戏创建一个好的地图设置。或者等等,也许这个问题是关于我为FTG创建statspage的疯狂想法。对,可能是。可惜FTG MP没用。你看过新的测试版了吗?我没有,我想现在就去看看,但我似乎再也不能访问私人FTG测试版论坛了。已经关门了吗?我仍然是官方FTG测试权限组的成员,所以我真的不明白为什么我不能访问论坛。我甚至可以访问该项目,并提交bug:你是在尝试编写自己的解析器吗?是的,我有一个项目将为eu2保存文件构建一些内部结构,然后对其进行修改并尝试再次将其写入文件。基本上,我想做的是将某些值随机化,为MP游戏创建一个好的地图设置。或者等等,也许这个问题是关于我为FTG创建statspage的疯狂想法。对,可能是。可惜FTG MP没用。你看过新的测试版了吗?我没有,我想现在就去看看,但我似乎再也不能访问私人FTG测试版论坛了。已经关门了吗?我仍然是官方FTG测试权限组的成员,所以我真的不明白为什么我不能访问论坛。我甚至可以访问该项目,并提交bug:S