2014-09-24 32 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