如何拆分字符串数组?

Posted

技术标签:

【中文标题】如何拆分字符串数组?【英文标题】:How to split a String array? 【发布时间】:2011-03-03 08:41:09 【问题描述】:

意图是取当前行(包含逗号的字符串),用“”(修剪空格)替换空格,最后将拆分的字符串元素存储到数组中。

为什么这不起作用?

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

【问题讨论】:

试过了,replaceAll("\\s", "").split(",")。这似乎有效。这是正确的吗? 解释一下它正在做什么和你期望它做什么会很有帮助。 您似乎正在尝试解析 CSV 文件。请注意,CSV 格式比乍看起来要复杂得多(由于处理值中的元字符的复杂性)。您应该使用库来执行此操作吗? @01:那是一个愚蠢的编辑。介意解释一下吗?现在,我正在恢复它。 @Konrad: 01 还添加了[beginner][footer] 这个问题***.com/questions/3050284/… 【参考方案1】:

关于正则表达式与非正则表达式方法

String 类有以下方法:

非正则表达式方法: String replace(char oldChar, char newChar) String replace(CharSequence target, CharSequence replacement) boolean startsWith(String prefix) boolean endsWith(String suffix) boolean contains(CharSequence s) 正则表达式方法: String replaceAll(String regex, String replacement) String replaceFirst(String regex, String replacement) String[] split(String regex) boolean matches(String regex)

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

其他常见的陷阱包括:

split(".")(当表示字面句号时) matches("pattern") 是一个 整个 字符串匹配! 没有contains("pattern");请改用matches(".*pattern.*")

在番石榴的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 不能省略返回数组开头/中间的空字符串。它只能省略 trailing 空字符串。另请注意,replaceAll 可能会过度“修剪”空格。您可以使正则表达式更复杂,以便它只修剪分隔符,但Splitter 解决方案绝对更具可读性和更易于使用。

Guava 还有(在许多其他美妙的东西中)一个非常方便的Joiner

System.out.println(
    Joiner.on("... ").skipNulls().join("Oh", "My", null, "God")
);
// prints "Oh... My... God"

【讨论】:

【参考方案2】:

我认为你想要替换所有而不是替换。

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

【讨论】:

"\s" 不是有效的 Java 字符串。应该是"\\s""\\s+" 相同) @Carlos - 有趣的是,这就是我写的,但因为我没有把它放在code 标记中,所以它显示为\s 而不是\\s 首先,您不能在替换中使用正则表达式,只能在搜索部分使用。其次,这不会删除所有空格,因为它错过了常见的非 ASCII 空格代码点,如 U+00A0 NO-BREAK SPACE 由于 Java 错误直到 Java 7 才修复,即使那样你也必须将 "(?U)" 嵌入到你的模式让\s 匹配Unicode 空白。如果你习惯了像 Perl 这样的语言,它们的正则表达式已经默认采用 Unicode,很容易忽略它们在 Java 中没有这样做。【参考方案3】:

你写的和代码不符:

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

通过代码,您希望删除所有空格并在逗号处分割结果字符串(未描述)。这可以按照 Paul Tomblin 的建议进行。

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

如果要在逗号处拆分并从结果部分中删除前导和尾随空格(修剪),请使用:

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

(需要trim() 来删除第一个部分的前导空格和最后一个部分的尾随空格)

【讨论】:

【参考方案4】:

如果您需要重复执行此操作,我建议您改用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,因为每次调用都涉及编译正则表达式然后替换。

【讨论】:

以上是关于如何拆分字符串数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在awk中将分隔字符串拆分为数组?

如何拆分camelCase字符串并检查每个拆分词是不是是数组的一部分?

如何首先“将字符串拆分为数组”然后“向该数组添加内容”? || C# 控制台应用程序

如何将字符串数组拆分为新的字符串数组并删除重复项

如何拆分数组中的字符串[重复]

如何在 C++ 中将字符串拆分为数组