2012-11-11 5 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

정규식에서 함수를 호출하여 JavaScript에서이 작업을 수행 할 수 있습니다 (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"(산소)가 있어야하는 수식에 실수로 0을 넣었습니까? 일치하는 경우 :

"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

미안, 내가 그랬다고 생각해. 이렇게 압축이 풀리면 C10으로 1을 추가하여 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)); 
} 

출력 :

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 
그런 다음, 개별 구성 요소를 분할 split()에 중첩 호출을 사용하고 싶다면

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

+0

의견을 삭제했습니다. 내 의견이 잘못되었다는 증거 +1. 좋은 해결책입니다. –

+0

아마도 내 솔루션보다 청소기가 있지만 성능상의 차이가 있는지 알고 싶습니다 ... 또한 패턴을 사용하여 매번 정규식을 다시 컴파일하지 않아도됩니다. – jrtc27

+0

도움 주셔서 감사합니다. – Joe24

관련 문제