2010-09-23 163 views
11

我有这个字符串(Java 1.5中):如何在Java中分割字符串并保留分隔符?

:alpha;beta:gamma;delta 

我需要一个数组:

{":alpha", ";beta", ":gamma", ";delta"} 

什么是最便捷的方式做到这一点在Java中?

+0

我编辑你的问题的标题,使之成为更通用的 – Bozho 2010-09-23 11:05:04

回答

26
str.split("(?=[:;])") 

这会给你所需的数组,只有空的第一项。并且:

str.split("(?=\\b[:;])") 

这将给出没有空的第一项的数组。

  • 这里的关键是(?=X)这是一个零宽度正先行(非捕获构建体)(参见regex pattern docs)。
  • [:;]手段“要么;或:”
  • \b是字边界 - 它的存在,以便不考虑所述第一:为定界符(因为它是该序列的开头)
+0

'(?= X)'是“零宽度正视向前”,非捕获组是“(?:X)”。这将无法正确与非捕获组... – 2010-09-23 11:11:42

+0

@Carlos Heuberger你能解释更多吗?它实际上以这种方式工作(测试它),但我可能错过了某些东西 – Bozho 2010-09-23 11:13:26

+1

它的工作原理,但序列'(?= X)'不被称为“非捕获组”,或者至少不是简单的“非捕获组” 。它被称为“零宽度正向预览”。 “非捕获组”是“(?:X)”。 (抱歉我的英文不好) – 2010-09-23 11:16:12

4

为了保持分离器,你可以使用一个StringTokenizer

new StringTokenizer(":alpha;beta:gamma;delta", ":;", true) 

这将产生分离为令牌。

要让它们作为您的代币的一部分,您可以使用String#splitlookahead

+3

“的StringTokenizer是一个遗留类” – Bozho 2010-09-23 10:56:38

+3

@Bozho没错,但我认为保持分隔符的这种特定用例没有被覆盖的字符串非常漂亮#split,这需要一些详细的正则表达式知识来获得。 – 2010-09-23 11:00:10

+0

确实如此,它使用StringTokenizer更清晰一些,因为它具有所需的选项作为布尔参数。 +1,关于遗产的观点仍然有效。 – Bozho 2010-09-23 11:02:21

-1

假设在字符串中的单词前面只有一个有限的分隔符(例如;,:等),您可以使用以下技术。 (道歉任何语法错误,但其一直以来我用Java的一段时间)

String toSplit = ":alpha;beta:gamma;delta " 
toSplit = toSplit.replace(":", "~:") 
toSplit = toSplit.replace(";", "~;") 
//repeat for all you possible seperators 
String[] splitStrings = toSplit.split("~") 
+0

这更简单。 – Joset 2010-09-23 11:20:45

+0

1.它不正确,因为它返回一个空的第0个元素。 2.它增加了由于重复而导致错误的可能性(即“:”必须与“〜:”配对)3.如果在其中一个子字符串中使用了特殊分隔符“〜”会怎么样? – 2010-09-23 13:20:57

+0

@Tony,我选择了“〜”作为示例,但可以使用适用于可用数据集的任何其他唯一分隔符。我不太明白它是如何增加错误的可能性 - 也许你可以澄清这一点。我承认它确实留下了一个空的第零个元素,这是一种失败的方法,但我想提出另一个不依赖于正则表达式的选项 – chillysapien 2010-09-23 13:58:03

1

您可以通过简单的使用模式和匹配类在Java至REGx做到这一点。

public static String[] mysplit(String text) 
    { 
    List<String> s = new ArrayList<String>(); 
    Matcher m = Pattern.compile("(:|;)\\w+").matcher(text); 
    while(m.find()) { 
    s.add(m.group()); 
    } 
    return s.toArray(new String[s.size()]); 
    } 
+0

一旦正则表达式djinni超出瓶子,我更喜欢Bozho的解决方案。 – 2010-09-23 14:42:19

+0

是的..我同意...上面只是一个alt的方式:) – Favonius 2010-09-23 15:05:13

1
/** 
* @param list an empty String list. used for internal purpose. 
* @param str String which has to be processed. 
* @return Splited String Array with delimiters. 
*/ 
public String[] split(ArrayList<String> list, String str){ 
    for(int i = str.length()-1 ; i >=0 ; i--){ 
    if(!Character.isLetterOrDigit((str.charAt(i)))) { 
     list.add(str.substring(i, str.length())); 
     split(list,str.substring(0,i)); 
     break; 
    } 
    } 
    return list.toArray(new String[list.size()]); 
} 
+1

这只是一个更多的方式!谁不知道像我这样的正则表达式:) – 2012-09-18 19:38:09

0

这应该与Java 1.5工作(Pattern.quote在Java 1.5中引入)。

// Split the string on delimiter, but don't delete the delimiter 
private String[] splitStringOnDelimiter(String text, String delimiter, String safeSequence){ 
    // A temporary delimiter must be added as Java split method deletes the delimiter 

    // for safeSequence use something that doesn't occur in your texts 
    text=text.replaceAll(Pattern.quote(delimiter), safeSequence+delimiter); 
    return text.split(Pattern.quote(safeSequence)); 
} 

如果第一元件的问题是:

private String[] splitStringOnDelimiter(String text, String delimiter, String safeSequence){ 
    text=text.replaceAll(Pattern.quote(delimiter), safeSequence+delimiter); 
    String[] tempArray = text.split(Pattern.quote(safeSequence)); 
    String[] returnArray = new String[tempArray.length-1]; 
    System.arraycopy(tempArray, 1, returnArray, 0, returnArray.length); 
    return returnArray; 
} 

例如,这里的 “一” 是分隔符:如果你是想要这个

1.: - 
2.: asd- 
3.: asd-g----10-9 
4.: asd 
5.: as j 
6.: add 

1.: -a 
2.: sd-a 
3.: sd-g----10-9a 
4.: sda 
5.: s ja 
6.: dd 

您切换:

safeSequence+delimiter 

splitStringOnDelimiter("-asd-asd-g----10-9asdas jadd", "a", "<>") 

你得到这个

delimiter+safeSequence 
相关问题