2014-09-24 28 views
0

我想写一个正则表达式匹配一串数字正好12次(可能有一个额外的数字在字符串的开始,然后我想丢弃)。正则表达式的烦恼

我写这个正则表达式时,他们都喜欢123.0123匹配这些数字(\ d + \ d +)。

String str3 = "0.0503 0.0485 0.0481 0.0491 0.0494 0.0489 0.0482 0.0485 0.0479 0.0487 0.0495 0.0487";

Pattern dataLinePattern = Pattern.compile("^(\\d+\\.\\d+\\s)?((\\d+\\.\\d+\\s*?){12})$"); Matcher m = dataLinePattern.matcher(str3); if (m.matches()) { System.out.println(m.group(2)); }

预期成果是:

0.0503 0.0485 0.0481 0.0491 0.0494 0.0489 0.0482 0.0485 0.0479 0.0487 0.0495 0.0487

但是,当我尝试类似

"^(\d+[\.\d]?\t?)?((\d+[\.\d]?\t*?){12})$"

"^(\d+(\.\d+)?\t?)?((\d+(\.\d+)?\t*?){12})$"

使小数位可选,正则表达式切断第一号,并打印仅在过去的11 ...我在做什么错?

输出:

0.0485 0.0481 0.0491 0.0494 0.0489 0.0482 0.0485 0.0479 0.0487 0.0495 0.0487 (失踪0.0503)

编辑:解决。 问题归结为可选的制表符分隔符\ t *?当该选项卡对于最后12个数字是可选的时,正则表达式引擎将返回并查找匹配并且发现最后一个数字将匹配两次:0和0487(在本示例中)

重新排列正则表达式以将每个数字开头的标签,而不是每个数字末尾的“可能”,这使得它可以工作。

Pattern.compile("([0-9.]+\t)?(([0-9.]+)(\t[0-9.]+){11})");

+0

工作对我来说.. – 2014-09-24 17:44:08

+0

它工作正常,检查http://regex101.com/r/ uO1lR6/1 – 2014-09-24 17:45:26

+0

第一个代码块中的代码有效,你是否尝试使用下面的2个替代正则表达式? (由于某些原因,它们没有以正确的java格式粘贴,所以你不得不加入反斜杠) – 2014-09-24 18:02:58

回答

1

试试这个:

String str3 = "0.0 0.0503 0.0485 0.0481 0.0491 0.0494 0.0489 0.0482 0.0485 0.0479 0.0487 0.0495 0.0487";  

Pattern dataLinePattern = Pattern 
     .compile(".*\\s+((\\d+(\\.\\d+)?)(\\s+(\\d+(\\.\\d+)?)){11})\\s*$"); 
Matcher m = dataLinePattern.matcher(str3); 

if (m.matches()) { 
    System.out.println(m.group().trim().replaceAll("\\s+", " ")); 
} 

它打印:

0.0503 0.0485 0.0481 0.0491 0.0494 0.0489 0.0482 0.0485 0.0479 0.0487 0.0495 0.0487 
+0

不喜欢那些贪婪的量词,但你引导我走向正确的道路。模式dataLinePattern = Pattern.compile(“ ?([0-9] + \\吨)([0-9](+)(\\吨[0-9。] +){11})“); – 2014-09-24 20:08:55

+0

很酷。但是,不是第一组不必要的?你可以简单地把'。*'。 – elias 2014-09-24 20:46:53

+0

以及你应该使用。*?实际上,但第一组是明确写入,以使正则表达式运行得更快。 “。*”很贪婪,并且实际上会匹配整行,然后正则表达式引擎会回溯整行中的每个字符,以尝试匹配表达式的其余部分。这使得模式匹配更加低效。关于正则表达式,你应该总是尽可能的明确,对于小文件你可能没有看到任何区别,但对于大文件(想想30GB基因组序列),差异会变得巨大。 – 2014-09-25 12:40:44