2009-05-07 2 views
1

누구든지 이스케이프 시퀀스를 고려하여 문자에 문자열을 분할하는 방법을 알고 있습니까?문자열 분할 (특히 Java에서 java.util.regex 또는 다른 것으로)

예를 들어 문자가 ':'인 경우 "a : b"는 두 부분 ("a"와 "b")으로 나뉘어져 있지만 "a : b"는 전혀 분할되지 않습니다.

정규 표현식과 관련해서는 이것이 어렵다고 생각합니다.

+0

http://stackoverflow.com/questions/820172/how-to-split-a-comma-separated-string-while-ignoring-escaped-commas도 참조하십시오. –

답변

2

(?<=^|[^\\]): 당신이 가까이 가져하지만 탈출 슬래시를 해결하지 않고, 사전에

게달을 주셔서 감사합니다. (문자 그대로의 정규 표현식입니다. 물론 자바 문자열을 얻기 위해 슬래시를 이스케이프 처리해야합니다.)

(?<=(^|[^\\])(\\\\)*): 어때요? 나는 짝수 개의 슬래시가 앞에 오는 ':'를 만족해야한다고 생각합니다.

편집 :이 항목을 투표에 등록하지 마십시오. MizardX의 솔루션은 더 나은 :)

+0

키가 (? <= foo) 구조이며 긍정적 인 룩백을합니다. 일치하는 ':'앞에 오는 것을 확인해야합니다. –

+1

MizardX는 룩어백은 유한 길이를 가져야한다고 지적했습니다. 내 것은 그렇게 작동하지 않을 것이라고 추측하지 않습니다 (테스트하지 않았습니다). 나는 우리의 솔루션이 다른 점은 비슷하다고 생각합니다. 그의 라인은 여러 줄 시나리오 (확실하지 않음)에서 다르게 작용할 수도 있고 그렇지 않을 수도있는 "^ | [^ \\\]"을 사용하는 반면, 슬래시 문자가 아닌지 확인하기 위해 음수 배역을 사용하는 것이 더 낫습니다. . –

+1

(^ | [^ \\\])이 작동해야합니다.^문자열 대신 줄의 시작과 일치 할 수 있습니다. 그게 백 슬래시가 아니라고 보장하기 때문에 괜찮습니다. [^ \\\]은 개행과도 일치하므로 여러 줄 모드를 사용하지 않을 때도 아무런 문제가 없습니다. –

2

자바 (만큼 그들은 유한만큼) 가변 길이 모양 비하인드을 지원하기 때문에, 당신은 이런 식으로 작업을 수행 할 수 :

import java.util.regex.*; 

public class RegexTest { 
    public static void main(String[] argv) { 

     Pattern p = Pattern.compile("(?<=(?<!\\\\)(?:\\\\\\\\){0,10}):"); 

     String text = "foo:bar\\:baz\\\\:qux\\\\\\:quux\\\\\\\\:corge"; 

     String[] parts = p.split(text); 

     System.out.printf("Input string: %s\n", text); 
     for (int i = 0; i < parts.length; i++) { 
      System.out.printf("Part %d: %s\n", i+1, parts[i]); 
     } 

    } 
} 
  • (?<=(?<!\\)(?:\\\\){0,10})이를 위해 뒤에 보이는 짝수 개의 백 슬래시 (0을 포함하여 최대 10 개까지)

출력 :

Input string: foo:bar\:baz\\:qux\\\:quux\\\\:corge
Part 1: foo
Part 2: bar\:baz\\
Part 3: qux\\\:quux\\\\
Part 4: corge

또 다른 방법 대신 구분 기호에서 분할, 부품 자체와 일치하는 것입니다.

Pattern p2 = Pattern.compile("(?<=\\A|\\G:)((?:\\\\.|[^:\\\\])*)"); 
List<String> parts2 = new LinkedList<String>(); 
Matcher m = p2.matcher(text); 
while (m.find()) { 
    parts2.add(m.group(1)); 
} 

이상한 구문은 문자열의 시작과 끝에서 빈 조각의 경우를 처리해야한다는 점에서 유래합니다. 일치 항목이 정확히 0 인 경우 다음 시도는 한 문자 뒤에서 시작합니다. 그렇지 않으면 다른 빈 문자열과 일치하고 다른 하나는 ad infinitum & hellip입니다.

  • (?<=\A|\G:)은 문자열의 시작 부분 (첫 번째 부분) 또는 이전 일치 부분의 끝 부분과 그 뒤에 구분 기호가 표시됩니다. (?:\A|\G:)을 수행하면 첫 번째 조각이 비어 있으면 (입력은 구분 기호로 시작) 실패합니다.
  • \\.은 이스케이프 된 문자와 일치합니다.
  • [^:\\]은 (모두 \\.이기 때문에) 이스케이프 시퀀스에없는 문자와 일치합니다.
  • ((?:\\.|[^:\\])*)은 첫 번째 이스케이프되지 않은 구분 기호가 캡처 그룹 1에 들어갈 때까지 모든 문자를 캡처합니다.