Разделить строку на подстроки равной длины в Java - PullRequest
109 голосов
/ 21 сентября 2010

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

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

Аналогичный вопрос:

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

Ответы [ 20 ]

202 голосов
/ 21 сентября 2010

Вот версия regex для одной строки:

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 flag) не так гибок, как \G, и его нельзя использовать таким образом, даже если JS поддерживает lookbehind.

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

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

119 голосов
/ 21 сентября 2010

Ну, это довольно просто сделать грубой силой:

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;
}

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

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

  • Это не использует ни одно из реальных сопоставлений с регулярными выражениями. Это просто счет.
  • I подозреваю вышесказанное будет более эффективным, хотя в большинстве случаев это не имеет значения
  • Если вам нужно использовать переменные размеры в разных местах, у вас либо есть повторение, либо вспомогательная функция для построения самого регулярного выражения на основе параметра - ick.
  • Регулярное выражение, приведенное в другом ответе, сначала не компилировалось (недопустимое экранирование), а затем не работало. Мой код работал с первого раза. Это еще одно свидетельство удобства использования регулярных выражений по сравнению с простым кодом, IMO.
69 голосов
/ 21 сентября 2010

Это очень просто с 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);
}
12 голосов
/ 21 сентября 2010

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

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

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

8 голосов
/ 21 сентября 2010
public static String[] split(String src, int len) {
    String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)];
    for (int i=0; i<result.length; i++)
        result[i] = src.substring(i*len, Math.min(src.length(), (i+1)*len));
    return result;
}
6 голосов
/ 21 сентября 2010
public String[] splitInParts(String s, int partLength)
{
    int len = s.length();

    // Number of parts
    int nparts = (len + partLength - 1) / partLength;
    String parts[] = new String[nparts];

    // Break into parts
    int offset= 0;
    int i = 0;
    while (i < nparts)
    {
        parts[i] = s.substring(offset, Math.min(offset + partLength, len));
        offset += partLength;
        i++;
    }

    return parts;
}
3 голосов
/ 21 июня 2019

Вот однострочная версия, которая использует Java 8 IntStream для определения индексов начала среза:

String x = "Thequickbrownfoxjumps";

String[] result = IntStream
                    .iterate(0, i -> i + 4)
                    .limit((int) Math.ceil(x.length() / 4.0))
                    .mapToObj(i ->
                        x.substring(i, Math.min(i + 4, x.length())
                    )
                    .toArray(String[]::new);
3 голосов
/ 21 сентября 2010

Вы можете использовать substring из String.class (обработка исключений) или из Apache lang commons (он обрабатывает исключения для вас)

static String   substring(String str, int start, int end) 

Поместите это в петлю, и все готово.

3 голосов
/ 15 июля 2018

Вот реализация с одним вкладышем, использующая потоки Java8:

String input = "Thequickbrownfoxjumps";
final AtomicInteger atomicInteger = new AtomicInteger(0);
Collection<String> result = input.chars()
                                    .mapToObj(c -> String.valueOf((char)c) )
                                    .collect(Collectors.groupingBy(c -> atomicInteger.getAndIncrement() / 4
                                                                ,Collectors.joining()))
                                    .values();

Это дает следующий вывод:

[Theq, uick, brow, nfox, jump, s]
2 голосов
/ 07 февраля 2016

Я бы предпочел это простое решение:

String content = "Thequickbrownfoxjumps";
while(content.length() > 4) {
    System.out.println(content.substring(0, 4));
    content = content.substring(4);
}
System.out.println(content);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...