2011-05-08 4 views
2

StringTokenizer("...", "...", true) 동작을 재현하려면 Javas Pattern.split(..) 메서드와 함께 사용할 정규 표현식을 빌드 할 수 있습니까?String.split (..)에 의한 StringTokenizer 대체

입력이 사전 정의 된 토큰 문자와 그 사이에서 실행되는 임의의 임의의 문자열의 교번 순서로 분할되도록하십시오.

JRE 참조는 StringTokenizer을 나타내며 더 이상 사용되지 않으며 대신 String.split(..)을 사용할 수 있습니다. 그래서 거기에 가능한 것으로 간주됩니다.

split을 사용하려는 이유는 정규 표현식이 최적화 된 경우가 많기 때문입니다. 예를 들어, StringTokenizer은 안드로이드 플랫폼 VM에서 매우 느리지 만 정규식 패턴은 최적화 된 네이티브 코드로 실행됩니다.

+0

의 중복 가능성 [사항 String.split (와 문자열을 분할)과 구분 기호를 포함하는 방법이 있나요? (http://stackoverflow.com/questions/275768/split-string-with-string-split-and-the-delimiters) – CoolBeans

+0

동일한 아이디어를 갖고 있지만 답변이없는 주석이없는 "Code Challange"가 있습니다 그것은 보인다. 구분 기호를 포함하고 싶지 않지만 별개의 토큰으로 가져옵니다. – dronus

+0

어쩌면 "나는 현학적 인 질문이며 정확하게 묻는 질문에 답변해야한다"라는 문구가 있어야 할 것입니다 :-) – dronus

답변

1

split에 대한 설명서에는이 동작이 지정되어 있지 않으며 배열의 크기를 알 수있는 단 하나의 선택적 매개 변수가 있습니다.

또한이 기능을 사용할 수 있다고 생각할 수있는 다른 클래스를 살펴보면 스캐너도 마찬가지입니다. 따라서 Tokenizer가 더 이상 사용되지 않는 경우에도 Tokenizer를 계속 사용하는 것이 가장 쉬운 방법이라고 생각합니다. 자신의 수업을 작성하는 것보다 낫지 만, 너무 어려워서는 안되지만 (정말로 사소한 것) 나는 시간을 보내는 더 좋은 방법을 생각할 수 있습니다.

+0

'String.split()'은 정규의 정규식을 취하고 왜 그것이 왜 가능하지 않아야하는지 분명하지 않습니다. 똑똑한 표정? – dronus

+0

+1 작업에 적합한 도구를 사용하도록 권장합니다. StringTokenizer는 가치가 떨어지지 않으며 원하는대로 정확하게 처리합니다. String.split (...)이 의도하지 않은 작업을 수행하도록 강제하지 마십시오. 비록 그것이 작동하도록 할 수 있다고하더라도, 아무도 실제로 사용 된 정규 표현식을 이해할 수는 없습니다. 단순하게 유지하십시오. 위 CoolBeans에서 제공 한 링크를 보셨습니까? 이 코드는 StringTokenizer가 쉽게 수행 할 수있는 무언가를 시도하는 데 끔찍한 일입니다. – camickr

+0

현재 안드로이드 플랫폼에서'Pattern.split (..)'을 사용하고 있습니다. VM이 다소 느리고'StringTokenizer'의 구현은 그리 효율적이지 않습니다. 반면 정규 표현식은 기본적으로 플랫폼에 구현되어 매우 빠르므로 'Pattern.split (..)'이 있습니다. – dronus

1

정규식 패턴이 당신에게 도움이 될 수 있습니다

Patter p = Pattern.compile("(.*?)(\\s*)"); 
//put the boundary regex in between the second brackets (where the \\s* now is) 
Matcher m = p.matcher(string); 
int endindex=0; 
while(m.find(endindex)){ 
//m.group(1) is the part between the pattern 
//m.group(2) is the match found of the pattern 
endindex = m.end(); 
} 
//then the remainder of the string is string.substring(endindex); 
1
import java.util.List; 
import java.util.LinkedList; 
import java.util.regex.Pattern; 
import java.util.regex.Matcher; 

public class Splitter { 


public Splitter(String s, String delimiters) { 
    this.string = s; 
    this.delimiters = delimiters; 
    Pattern pattern = Pattern.compile(delimiters); 
    this.matcher = pattern.matcher(string); 
} 

public String[] split() { 
    String[] strs = string.split(delimiters); 
    String[] delims = delimiters(); 
    if (strs.length == 0) { return new String[0];} 
    assert(strs.length == delims.length + 1); 
    List<String> output = new LinkedList<String>(); 
    int i; 
    for(i = 0;i < delims.length;i++) { 
     output.add(strs[i]); 
     output.add(delims[i]); 
    } 
    output.add(strs[i]); 
    return output.toArray(new String[0]); 
} 

private String[] delimiters() { 
    List<String> delims = new LinkedList<String>(); 
    while(matcher.find()) { 
     delims.add(string.subSequence(matcher.start(), matcher.end()).toString()); 
    } 
    return delims.toArray(new String[0]); 
} 

public static void main(String[] args) { 
    Splitter s = new Splitter("a b\tc", "[ \t]"); 
    String[] tokensanddelims = s.split(); 
    assert(tokensanddelims.length == 5); 
    System.out.print(tokensanddelims[0].equals("a")); 
    System.out.print(tokensanddelims[1].equals(" ")); 
    System.out.print(tokensanddelims[2].equals("b")); 
    System.out.print(tokensanddelims[3].equals("\t")); 
    System.out.print(tokensanddelims[4].equals("c")); 
} 


private Matcher matcher; 
private String string; 
private String delimiters; 
} 
+0

글쎄, 멋지다. 그러나 그것은 필자의 경우에는 필요하지 않은 구분 기호와 토큰을 분리한다. 'StringTokenizer'의 동작을 구분자/토큰 시퀀스 출력을 번갈아 바꾸는 것을 좋아합니다. – dronus

+0

좋아, 어때? –

+0

누락 된'import' 문을 추가했습니다. 잘 작동합니다. 그러나 더 성능이 좋은 뭔가에 의해'StringTokenizer'를 대체하지는 않습니다. 나는 하나의 RegExp가 안드로이드 플랫폼에서 기본적으로 빠르게 처리되기 때문에'split'과 함께 사용되는 단일 RegExp가 작업을 수행 할 수 있기를 희망했습니다. – dronus

관련 문제