Java中类似于Python中字符串分割的方法是什么?

4

Java中的字符串split(regex)函数会在所有regex实例处进行分割。Python的partition函数仅在给定分隔符的第一个实例处进行分割,并返回一个{left,separator,right}元组。

我该如何在Java中实现类似于partition的功能?

例如:

"foo bar hello world".partition(" ")

应该变成

"foo", " ", "bar hello world"
  • 是否有外部库已经提供了这个实用程序?

  • 如果没有外部库,我该如何实现它?

  • 能否在没有外部库和正则表达式的情况下实现它?

注:我不想使用split(" ",2),因为它不返回分隔符字符。

5个回答

5
虽然不完全符合您的要求,但有一个“split”的第二个版本(请参见此处),它带有一个“limit”参数,告诉它将字符串分成的最大分区数。
因此,如果您在Java中调用了以下代码:
"foo bar hello world".split(" ", 2);

您将获得数组:

["foo", "bar hello world"]

这大致是您想要的,但分隔符字符未嵌入索引1。如果您真的需要这一点,则需要自己处理,但希望您只是想要限制拆分数量。


保留分隔符字符是一个要求。 - Iain Sproat
1
@sprocketonline: 啊,我明白了。我原以为数组索引只是分隔符regex(因此很容易剪接),但现在我明白了它是与匹配这个正则表达式的字符序列(非常不同)。既然如此,请按照polygenelubricants的答案去执行,因为最简单的方法是明确使用Matchers。 - Andrzej Doyle
在Chrome 48中无法工作: "foo bar hello world".split(" ", 2); ["foo", "bar"] - pbanka
1
@pbanka: 这是因为Chrome控制台不执行Java代码。(这个事实也是Javascript中合法的语法,纯属巧合。) - Andrzej Doyle
@AndrzejDoyle - 哦,抱歉。我读错了帖子的标题。 - pbanka

5

String.split(String regex, int limit)方法与您想要的非常接近。从文档中可以看到:

limit参数控制模式应用的次数,因此影响结果数组的长度。

  • 如果限制n大于零,则模式最多将应用n-1次,数组的长度不会超过n,并且数组的最后一个条目将包含所有匹配的分隔符之后的输入。
  • 如果n为非正数,则模式将尽可能地应用,并且数组可以具有任何长度。
    • 如果n为零,则模式将尽可能地应用,数组可以具有任何长度,并且末尾的空字符串将被丢弃。

以下是一个示例,展示了这些差异(如在ideone.com上看到的):

static void dump(String[] ss) {
    for (String s: ss) {
        System.out.print("[" + s + "]");
    }
    System.out.println();
}
public static void main(String[] args) {
    String text = "a-b-c-d---";

    dump(text.split("-"));
    // prints "[a][b][c][d]"

    dump(text.split("-", 2));
    // prints "[a][b-c-d---]"

    dump(text.split("-", -1));
    // [a][b][c][d][][][]
    
}

保留分隔符的分割

如果您需要与分割类似的功能,并且还想获取与任意模式匹配的分隔符字符串,可以使用Matcher,然后在适当的索引处使用substring

以下是一个示例(如在ideone.com上看到的那样):

static String[] partition(String s, String regex) {
    Matcher m = Pattern.compile(regex).matcher(s);
    if (m.find()) {
        return new String[] {
            s.substring(0, m.start()),
            m.group(),
            s.substring(m.end()),
        };
    } else {
        throw new NoSuchElementException("Can't partition!");
    }
}
public static void main(String[] args) {
    dump(partition("james007bond111", "\\d+"));
    // prints "[james][007][bond111]"
}

正则表达式\d+当然是匹配任何数字字符(\d)重复一次或多次(+)。

1
迄今为止,这是唯一正确的答案!对于介绍ideone,我还要加上一个虚拟的+1,它看起来非常有用。 - Andrzej Doyle
@Andrzej:是的,使用ideone,你可以快速(i)查看它是否有效(ii)编辑并自行测试。 - polygenelubricants

2
这个怎么样:
String partition(String string, String separator) {
    String[] parts = string.split(separator, 2);
    return new String[] {parts[0], separator, parts[1]};
}

顺便提一下,你需要在这里添加一些输入和输出检查 :)


split函数的分隔符参数是一个正则表达式。 - Antti Haapala -- Слава Україні

0
使用:
"foo bar hello world".split(" ",2)
默认情况下,分隔符是空格。

请仔细阅读 - 这不是对_此_问题的答案。 - Péter Török
这个程序相关的内容从英语翻译成中文。只返回翻译后的文本:这不返回分隔符,这是问题的要求。 - Iain Sproat

0
这个功能已经有外部库提供了吗?
据我所知没有。
如果没有外部库,我该如何实现它?能否在不使用外部库和正则表达式的情况下实现?
当然可以,这很容易;只需使用 String.indexOf()String.substring()。但是,Java 没有元组数据类型,因此您必须返回数组、列表或编写自己的结果类。

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