2011-05-08 138 views
2

是否有可能構建一個正則表達式,以便與Javas Pattern.split(..)方法一起使用來重現StringTokenizer("...", "...", true)行爲?通過String.split替換StringTokenizer(..)

這樣輸入就會被分割成預定義的令牌字符和在它們之間運行的任何字符串的交替序列。

JRE參考狀態StringTokenizer它應該被視爲不推薦使用,並且可以使用String.split(..)替代方式。所以它被認爲是可能的。

我想使用split的原因是正則表達式通常是高度優化的。例如,StringTokenizer在Android平臺虛擬機上很慢,而正則表達式模式通過優化的本地代碼執行。

+0

的可能重複[有沒有辦法分裂與String.split(串)和包括分隔符?(http://stackoverflow.com/questions/275768/is-there-a-way-split-strings-with-string-split-and-include-the-delimiters) – CoolBeans 2011-05-08 18:56:29

+0

有一個沒有註釋的「代碼挑戰」有相同的想法,但沒有答案它似乎。我不想包含分隔符,但可以將它們作爲不同的標記。 – dronus 2011-05-08 19:04:55

+0

也許應該有一個「我很迂腐,正確回答問題」標誌:-) – dronus 2011-05-08 20:15:35

回答

1

考慮到split的文檔沒有指定這種行爲,並且只有一個可選參數來告訴數組應該是多大。不,你不能。

另外看看我能想到的唯一的其他類,可以有這個功能 - 掃描儀 - 它也沒有。所以我認爲最簡單的方法就是繼續使用Tokenizer,即使它已被棄用。比寫自己的班級要好得多 - 雖然這不應該太難(真的很微不足道),我可以想出更好的方式來度過一段時間。

+0

但是'String.split()'需要一個abitrary正則表達式,它對我來說並不明顯,爲什麼它不應該是可能的聰明的表情? – dronus 2011-05-08 19:12:00

+0

+1,建議使用正確的工具進行作業。 StringTokenizer不被剝奪,並且完全按照你的意願。不要強制String.split(...)嘗試去做一些它沒有設計的東西。即使你能使它正常工作,沒有人會真正理解所使用的正則表達式。把事情簡單化。你看過上面CoolBeans提供的鏈接嗎?該代碼是可怕的嘗試和做一些很容易通過StringTokenizer完成的事情。 – camickr 2011-05-08 19:12:32

+0

目前我喜歡在Android平臺上使用'Pattern.split(..)',因爲虛擬機在那裏速度很慢,'StringTokenizer'的實現效率不高。另一方面,正則表達式在本地平臺上實現並且速度很快,所以'Pattern.split(..)'是。 – dronus 2011-05-08 19:17:55

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 2011-05-08 20:07:08

+0

好的,這個怎麼樣? – 2011-05-08 23:55:36

+0

我添加了缺少的'import'語句。工作正常。它不會用更高性能的東西代替'StringTokenizer'。我希望在split平臺上使用單個RegExp可以完成這項工作,因爲在Android平臺上可以快速處理單個RegExp。 – dronus 2011-05-09 21:39:24