2012-11-11 29 views
2

我正在製作一個程序,讓用戶輸入化學物質,例如C9H11N02。當他們進入我想分裂成碎片,所以我可以讓它像C9,H11,N,02.當我有這樣的我想要改變它,所以我可以使它C10H12N203,然後把它放回來一起。這是我迄今爲止所做的。使用正則表達式我已經使用我可以提取整數值,但我怎麼會得到C10,H11等。?在Java中使用正則表達式分割輸入

System.out.println("Enter Data"); 

Scanner k = new Scanner(System.in); 
String input = k.nextLine(); 

String reg = "\\s\\s\\s"; 
String [] data; 

data = input.split(reg); 

int m = Integer.parseInt(data[0]); 
int n = Integer.parseInt(data[1]); 
+0

@BheshGurung不太確定... – Bohemian

+0

我不明白,你想用什麼字符串溢出空格作爲分隔符? – PermGenError

+0

你可以通過從正則表達式調用函數來實現這一點 - 請參閱http://stackoverflow.com/questions/1742798/increment-a-number-in-a-string-in-with-regex - 但這是Java ... – DNA

回答

1

我相信下面的代碼應該允許你提取各種元素及其相關的計數。當然,括號使事情變得更加複雜,但是你沒有問他們!

Pattern pattern = Pattern.compile("([A-Z][a-z]*)([0-9]*)"); 
Matcher matcher = pattern.matcher(input); 
while (matcher.find()) { 
    String element = matcher.group(1); 
    int count = 1; 
    if (matcher.groupCount > 1) { 
     try { 
      count = Integer.parseInt(matcher.group(2)); 
     } catch (NumberFormatException e) { 
      // Regex means we should never get here! 
     } 
    } 
    // Do stuff with this component 
} 
+0

該模式將得到CH4的錯誤結果,例如 - 它應該返回[C,H4],但我認爲它會返回[CH4]。兩個字母的化學符號總是大寫 - 小寫。 – DNA

+0

啊,修理 - 謝謝! – jrtc27

+0

現在應該工作。 – jrtc27

2

您是否意外地將零寫入其中字母「O」(氧氣)應該是的那些公式中?如果是這樣的話:

"C10H12N2O3".split("(?<=[0-9A-Za-z])(?=[A-Z])"); 

[C10, H12, N2, O3] 

"CH2BrCl".split("(?<=[0-9A-Za-z])(?=[A-Z])"); 

[C, H2, Br, Cl] 
+0

對不起,我想我是。一旦它被提取像這樣我可以進一步下降,所以我可以添加1到C10使其成爲C11? – Joe24

+0

+1,用於lookbehind - 但這對於雙字母化學符號的某些組合不起作用,例如CH2BrCl – DNA

+0

@DNA:我認爲現在應該修復。 –

3

它可以使用look arounds來完成:

String[] parts = input.split("(?<=.)(?=[A-Z])"); 

查找變通是零寬度,非消耗的斷言。

此正則表達式將輸入其中兩個外表變通匹配:

  • (?<=.)意味着「有之前的字符」(即未在輸入的開始)
  • (?=[A-Z])的意思是「下一個字符是一個大寫字母」(所有的元素與A-Z開始)

這是一個測試,包括對一些邊緣情況下,雙字符符號:

public static void main(String[] args) { 
    String input = "C9KrBr2H11NO2"; 
    String[] parts = input.split("(?<=.)(?=[A-Z])"); 
    System.out.println(Arrays.toString(parts)); 
} 

輸出:

[C9, Kr, Br2, H11, N, O2] 

然後,如果您想分裂的各個組件,使用split()嵌套調用:

public static void main(String[] args) { 
    String input = "C9KrBr2H11NO2"; 
    for (String component : input.split("(?<=.)(?=[A-Z])")) { 
     // split on non-digit/digit boundary 
     String[] symbolAndNumber = component.split("(?<!\\d)(?=\\d)"); 
     String element = symbolAndNumber[0]; 
     // elements without numbers won't be split 
     String count = symbolAndNumber.length == 1 ? "1" : symbolAndNumber[1]; 
     System.out.println(element + " x " + count); 
    } 
} 

輸出:

C x 9 
Kr x 1 
Br x 2 
H x 11 
N x 1 
O x 2 
+0

我刪除了我的評論。 +1證明我的評論是錯誤的。這是一個很好的解決方案。 –

+0

可能比我的解決方案更乾淨,但我有興趣查看性能方面是否存在任何差異......另外,您可能需要使用「模式」,以便您不必每次都重新編譯正則表達式。 – jrtc27

+0

感謝您的幫助 – Joe24