2011-05-08 133 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