2012-03-02 71 views
3

我的目標是匹配第一個0和零後十進制值的所有內容。如果第一個小數位是零,那麼我也想匹配小數點。如果沒有小數點,則不捕獲任何數據。正則表達式積極lookbehind災難

這裏有我想要的一些例子:

180.57// should capture the "0123" on the end 
180.570 // should capture the "0" on the end 
180.// should capture the ".0123" on the end 
180.0  // should capture the ".0" on the end 
18// should capture nothing 
180  // should capture nothing 

如果小數點後第一位是0,則使得比賽很簡單:

(\.0.*) 

我的問題是第一位小數時匹配地方不是0.我相信積極lookbehind將解決這個問題,但我無法讓它正常工作。這裏是我嘗試過的一個正則表達式:

(?<=^.*\..*)0.* 

這個正則表達式最終將在Java中使用。

UPDATE:

我要使用這個表達式擺脫數字的和可能的小數點上使用Java的replaceAll方法的字符串的結尾。我將通過用空字符串替換捕獲組來完成此操作。這是我想要的更好的例子。

String case1 = "180.570123"; 
String case2 = "180.570"; 
String case3 = "180.0123"; 
String case4 = "180.0"; 
String case5 = "180123"; 
String case6 = "180"; 

String result = null; 

result = case1.replaceAll("THE REGEX I NEED", ""); 
System.out.println(result); // should print 180.57 

result = case2.replaceAll("THE REGEX I NEED", ""); 
System.out.println(result); // should print 180.57 

result = case3.replaceAll("THE REGEX I NEED", ""); 
System.out.println(result); // should print 180 

result = case4.replaceAll("THE REGEX I NEED", ""); 
System.out.println(result); // should print 180 

result = case5.replaceAll("THE REGEX I NEED", ""); 
System.out.println(result); // should print 18

result = case6.replaceAll("THE REGEX I NEED", ""); 
System.out.println(result); // should print 180 

此外,我在http://gskinner.com/RegExr/

回答

3

測試這些regexs您可以使用此表達式:

\.[1-9]*(0\d*) 

你想將是第一個捕獲組中的內容。 (除小數點)

如果你想捕捉到小數點也一樣,你可以使用:

(?:\.[1-9]+|(?=\.))(\.?0\d*) 

例(online):

Pattern p = Pattern.compile("(?:\\.[1-9]+|(?=\\.))(\\.?0\\d*)"); 

String[] strs = {"180.570123", "180.570", "180.0123", "180.0", "180123", "180", "180.2030405"}; 

for (String s : strs) { 
    Matcher m = p.matcher(s); 
    System.out.printf("%-12s: Match: %s%n", s, 
     m.find() ? m.group(1) : "n/a"); 
} 

輸出:

180.57: Match:
180.570  : Match: 0 
180.: Match: .
180.0  : Match: .0 
18: Match: n/a 
180   : Match: n/a 
180.2030405 : Match: 030405 
+0

捕獲情況1錯誤,不捕捉的情況下2或者4。 – ubiquibacon 2012-03-02 14:10:20

+1

@typoknig,已更新。案例1總是匹配正確。 *使用第一個捕獲組的內容,而不是整個匹配。* – Qtax 2012-03-02 14:14:39

+0

啊,我明白了。正如你所說的那樣,在使用第一個捕獲組的內容時它似乎工作正常。非常感謝! – ubiquibacon 2012-03-02 14:54:04

0

後視可能是矯枉過正。這一個行之有效 - >

/\.\d*(0\d*)/

+0

錯誤地捕獲了案例1,根本沒有捕獲案例2,3或4。 – ubiquibacon 2012-03-02 14:15:48

+0

但不是這種情況下捕獲小數點和以下0.你期望在這裏:'180.0407' – Ethan 2012-03-02 14:17:14

+0

該組捕獲你想要的,除了.0的情況。 – Ethan 2012-03-02 14:18:04

1

我會寫一個小功能做的提取,而不是正則表達式。

private String getZeroPart(final String s) { 
     final String[] strs = s.split("\\."); 
     if (strs.length != 2 || strs[1].indexOf("0") < 0) { 
      return null; 
     } else { 
      return strs[1].startsWith("0") ? "." + strs[1] : strs[1].substring(strs[1].indexOf("0")); 
     } 
    } 

來測試它:

final String[] ss = { "180.570123", "180.570", "180.0123", 
"180.0", "180123", "180", "180.2030405","180.5555" }; 

     for (final String s : ss) { 
      System.out.println(getZeroPart(s)); 
     } 

輸出:


0 
.
.0 
null 
null 
030405 
null 

更新

基於問題的編輯。做的方法的一些變化,以獲得正確的數字:

private String cutZeroPart(final String s) { 
    final String[] strs = s.split("\\."); 
    if (strs.length != 2 || strs[1].indexOf("0") < 0) { 
     return s; 
    } else { 
     return strs[1].startsWith("0") ? strs[0] : s.substring(0, strs[0].length() + strs[1].indexOf("0") + 1); 
    } 
} 

輸出:

180.57-> 180.57 
180.570 -> 180.57 
180.-> 180 
180.0 -> 180 
18-> 18
180 -> 180 
180.2030405 -> 180.2 
180.5555 -> 180.5555 
+0

謝謝你。這是很好的選擇,但我認爲正則表達式有點乾淨:) – ubiquibacon 2012-03-02 16:54:17

0

你可以試試這個:

 Matcher m = Pattern.compile("(?<=(\\.))(\\d*?)(0.*)").matcher("180.2030405"); 
     String res=""; 
     if(m.find()){ 
      if(m.group(2).equals("")){ 
       res = "."+m.group(3); 
      } 
      else{ 
       res = m.group(3); 
      } 
     }