Вопрос-ответ

Split string to equal length substrings in Java

Разбиение строки на подстроки равной длины в Java

Как разбить строку "Thequickbrownfoxjumps" на подстроки равного размера в Java. Например. "Thequickbrownfoxjumps" на выходе должно быть 4 подстроки одинакового размера.

["Theq","uick","brow","nfox","jump","s"]

Похожий вопрос:

Разбиение строки на подстроки равной длины в Scala

Переведено автоматически
Ответ 1

Вот однострочная версия регулярного выражения:

System.out.println(Arrays.toString(
"Thequickbrownfoxjumps".split("(?<=\\G.{4})")
));

\G это утверждение нулевой ширины, что соответствует позиции, где предыдущий матч закончился. Если там был не предыдущий матч, это соответствует началу ввода, так же, как \A. Заключающий в себе указатель назад соответствует позиции, которая находится на расстоянии четырех символов от конца последнего совпадения.

И lookbehind, и \G являются расширенными функциями регулярных выражений, которые поддерживаются не всеми вариантами. Кроме того, \G не реализован последовательно во всех вариантах, которые его поддерживают. Этот трюк будет работать (например) в Java, Perl, .NET и JGsoft, но не в PHP (PCRE), Ruby 1.9+ или TextMate (оба Oniguruma). В JavaScript /y (флаг sticky) не такой гибкий, как \G, и его нельзя было бы использовать таким образом, даже если бы JS поддерживал lookbehind .

Я должен упомянуть, что я не обязательно рекомендую это решение, если у вас есть другие варианты. Решения без регулярных выражений в других ответах могут быть длиннее, но они также самодокументируются; этот как раз противоположен этому. ;)

Кроме того, это не работает в Android, который не поддерживает использование \G в lookbehinds.

Ответ 2

Что ж, это довольно легко сделать с помощью простых арифметических и строковых операций:

public static List<String> splitEqually(String text, int size) {
// Give the list the right capacity to start with. You could use an array
// instead if you wanted.
List<String> ret = new ArrayList<String>((text.length() + size - 1) / size);

for (int start = 0; start < text.length(); start += size) {
ret.add(text.substring(start, Math.min(text.length(), start + size)));
}
return ret;
}

Примечание: это предполагает сопоставление единицы кода UTF-16 в соотношении 1: 1 (char, эффективно) с "символом". Это предположение не работает для символов за пределами базовой многоязычной плоскости, таких как эмодзи, и (в зависимости от того, как вы хотите подсчитывать вещи) для комбинирования символов.

Я не думаю, что для этого действительно стоит использовать регулярное выражение.

РЕДАКТИРОВАТЬ: Мои доводы в пользу отказа от использования регулярного выражения:


  • При этом не используется какое-либо реальное сопоставление регулярных выражений с шаблоном. Это просто подсчет.

  • Я подозреваю, что вышеописанное будет более эффективным, хотя в большинстве случаев это не будет иметь значения

  • Если вам нужно использовать переменные размера в разных местах, у вас есть либо repetition, либо вспомогательная функция для построения самого регулярного выражения на основе параметра - ick .

  • Регулярное выражение, приведенное в другом ответе, сначала не скомпилировалось (недопустимый экранирующий код), а затем не сработало. Мой код сработал с первого раза. Это скорее свидетельство удобства использования регулярных выражений по сравнению с обычным кодом, IMO.

Ответ 3

Это очень просто с Google Guava:

for(final String token :
Splitter
.fixedLength(4)
.split("Thequickbrownfoxjumps")){
System.out.println(token);
}

Вывод:

Theq
uick
brow
nfox
jump
s

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

String[] tokens =
Iterables.toArray(
Splitter
.fixedLength(4)
.split("Thequickbrownfoxjumps"),
String.class
);

Ссылка:

Примечание: Конструкция разделителя показана встроенно выше, но поскольку разделители неизменяемы и могут использоваться повторно, рекомендуется хранить их в константах:

private static final Splitter FOUR_LETTERS = Splitter.fixedLength(4);

// more code

for(final String token : FOUR_LETTERS.split("Thequickbrownfoxjumps")){
System.out.println(token);
}
Ответ 4

Если вы используете библиотеки общего назначения Google guava (и, честно говоря, любой новый проект Java, вероятно, должен быть), это безумно тривиально с классом Splitter:

for (String substring : Splitter.fixedLength(4).split(inputString)) {
doSomethingWith(substring);
}

и это все. Просто как!

java regex string