Java-эквивалент String раздела Python - PullRequest
4 голосов
/ 23 июня 2010

Функция разделения строки (регулярное выражение) Java разделяет все экземпляры регулярного выражения. Функция секционирования Python разбивает только первый экземпляр данного разделителя и возвращает кортеж {left, separator, right}.

Как мне добиться того, что делает раздел в Java?

, например

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

должно стать

"foo", " ", "bar hello world"
  • Есть ли внешняя библиотека, которая предоставляет эту утилиту уже?

  • как бы я этого достиг без внешняя библиотека?

  • И можно ли этого достичь без внешней библиотеки и без Regex?

NB. Я не ищу split ("", 2), так как он не возвращает символ разделителя.

Ответы [ 5 ]

5 голосов
/ 23 июня 2010

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) повторяется один или несколько раз (+).

5 голосов
/ 23 июня 2010

Хотя не точно , что вам нужно, есть вторая версия split , которая принимает параметр «limit», сообщающий ему максимальное количество разделов, на которые нужно разбить строку.

Итак, если вы позвонили (на Java):

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

Вы получите массив:

["foo", "bar hello world"]

это более или менее то, что вам нужно, за исключением того факта, что символ-разделитель не встроен в индекс 1. Если вам действительно нужен этот последний пункт, вам нужно сделать это самостоятельно , но, надеюсь, все, что вы конкретно хотели, это возможность ограничить количество разделений.

2 голосов
/ 23 июня 2010

Как насчет этого:

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

Кстати, вы должны добавить некоторые проверки ввода / результата в этом:)

0 голосов
/ 23 июня 2010

Существует ли внешняя библиотека, которая уже предоставляет эту утилиту?

Ни одного, о котором я знаю.

как бы мне этого добиться без внешней библиотеки? И можно ли этого достичь без внешней библиотеки и без Regex?

Конечно, это совсем не проблема; просто используйте String.indexOf() и String.substring(). Однако в Java нет типа данных кортежа, поэтому вам придется возвращать массив, список или писать свой собственный класс результатов.

0 голосов
/ 23 июня 2010

Использование:

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

По умолчанию в качестве разделителя используется пробел

...