Java中类似于Python的String partition的实现

4 投票
5 回答
5468 浏览
提问于 2025-04-16 00:19

Java中的字符串分割函数split(regex)会在所有符合正则表达式的地方进行分割。而Python的partition函数只会在给定的分隔符第一次出现的地方进行分割,并返回一个包含{左边部分,分隔符,右边部分}的元组。

我该如何在Java中实现partition的功能呢?

例如:

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

应该变成:

"foo", " ", "bar hello world"
  • 有没有现成的外部库可以提供这个功能?

  • 如果不使用外部库,我该怎么做?

  • 有没有办法在不使用外部库和正则表达式的情况下实现?

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

5 个回答

2

这样做怎么样:

String partition(String string, String separator) {
    String[] parts = string.split(separator, 2);
    return new String[] {parts[0], separator, parts[1]};
}

顺便说一下,你需要在这里添加一些输入和结果的检查哦 :)

5

虽然这不是你想要的完全效果,但有一个split的第二种版本,它可以接收一个“限制”参数,这个参数告诉它最多可以把字符串分成多少部分。

所以如果你在Java中这样调用:

"foo bar hello world".split(" ", 2);

你会得到一个数组:

["foo", "bar hello world"]

这个数组大致符合你的需求,除了分隔符字符没有出现在索引1的位置。如果你真的需要这个最后一点,那你就得自己处理了,但希望你只是想要限制分割的次数。

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) 重复一次或多次 (+)。

撰写回答