如何拆分字符串数组?

12

目的是获取当前行(包含逗号的字符串),用""替换空格并将拆分后的字符串元素存储到数组中。

为什么这样不起作用?

String[] textLine = currentInputLine.replace("\\s", "").split(",");

尝试了使用replaceAll("\s", "").split(","),看起来好像可以。这样做正确吗? - James Raitsev
解释一下它正在做什么和你期望它做什么之间的差异会很有帮助。 - Adam Crume
看起来你正在尝试解析一个CSV文件。请注意,CSV格式比首次看到时复杂得多(由于值中处理元字符的复杂性)。你应该使用库来完成这个任务吗? - Donal Fellows
1
@01:那是一个愚蠢的编辑。能解释一下吗?现在,我要撤销它。 - Konrad Rudolph
@Konrad:01还在这个问题http://stackoverflow.com/questions/3050284/appropriate-footwear-for-an-interview中添加了“[初学者]”和“[页脚]”。 - polygenelubricants
@polygenelubricants:是的,还有其他几篇帖子也是。我不确定那是不是一个喷子,所以我已经为此向版主举报了。 - Konrad Rudolph
4个回答

10

关于正则表达式和非正则表达式方法的选择

String类有以下方法:

因此,在这里我们看到了你的问题直接原因:你正在非正则表达式方法中使用一个正则表达式模式。您需要使用replaceAll而不是replace

其他常见错误包括:

  • split(".")(当想要一个文字句点时)
  • matches("pattern")是整个字符串匹配!
    • 没有contains("pattern"); 使用matches(".*pattern.*")代替

关于Guava的Splitter

根据您的需求,String.replaceAllsplit组合可能已足够完成工作。然而,更专业的工具是来自Guava的Splitter

这里是一个示例以展示区别:

public static void main(String[] args) {
    String text = "  one, two, , five (three sir!) ";

    dump(text.replaceAll("\\s", "").split(","));
    // prints "[one] [two] [] [five(threesir!)] "

    dump(Splitter.on(",").trimResults().omitEmptyStrings().split(text));
    // prints "[one] [two] [five (three sir!)] "
}

static void dump(String... ss) {
    dump(Arrays.asList(ss));
}
static void dump(Iterable<String> ss) {
    for (String s : ss) {
        System.out.printf("[%s] ", s);
    }
    System.out.println();       
}
请注意,String.split不能省略返回数组开头/中间的空字符串。它只能省略末尾的空字符串。此外,请注意replaceAll可能会过度"修剪"空格。您可以使正则表达式更加复杂,以便仅在定界符周围修剪,但Splitter解决方案肯定更易读且更简单易用。
Guava(还有许多其他美妙的东西)也有一个非常方便的Joiner工具。
System.out.println(
    Joiner.on("... ").skipNulls().join("Oh", "My", null, "God")
);
// prints "Oh... My... God"

6

我认为你想要使用replaceAll而不是replace。

replaceAll("\\s","")将删除所有空格,而不仅仅是多余的空格。如果这不是你想要的,你应该尝试replaceAll("\\s+","\\s")或类似的方法。


1
"\s" 不是有效的 Java 字符串。应该使用 "\s"(对于 "\s+" 也是如此)。 - user85421
1
@Carlos - 有趣的是,这就是我写的,但因为我没有将它放在 code 标记中,所以它显示为 \s 而不是 \\s - Paul Tomblin
1
首先,在替换部分中不能使用正则表达式,只能在搜索部分中使用。其次,这并没有删除所有的空格,因为它错过了常见的非ASCII空格代码点,如U+00A0 NO-BREAK SPACE,这是由于Java 7之前未修复的Java错误,即使在Java 7中修复了,你仍然需要将"(?U)"嵌入到你的模式中才能让\s匹配Unicode空格。如果你习惯于像Perl这样的语言,它们的正则表达式已经默认捕获Unicode,那么很容易忽略它们在Java中不这样做。 - tchrist

2

您写的内容与代码不符:

意图是获取包含逗号的当前行,存储所有空格修剪后的值,并将该行存储到数组中。

根据代码看,似乎您想要删除所有空格并在逗号处分割结果字符串(未描述)。可以按照Paul Tomblin建议的方式实现。

String[] currentLineArray = currentInputLine.replaceAll("\\s", "").split(",");

如果你想在逗号处进行分割,并从结果部分中去除前导和尾随空格(修剪),请使用:
String[] currentLineArray = currentInputLine.trim().split("\\s*,\\s*");

需要使用trim()函数来去除第一个部分的前导空格和最后一个部分的尾随空格。


0
如果您需要重复执行此操作,建议使用 java.util.regex.Patternjava.util.regex.Matcher
final Pattern pattern = Pattern.compile( regex);
for(String inp: inps) {
    final Matcher matcher = pattern.matcher( inpString);
    return matcher.replaceAll( replacementString); 
}

编译正则表达式是一项昂贵的操作,不建议反复使用String的replaceAll方法,因为每次调用都涉及到正则表达式的编译和替换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接