Разделить строку на равные символы

Как я мог разбить строку на несколько подстрок, где каждая подстрока содержит равные конечные символы? Такой как:

hello -> h, e, ll, o
helel -> h, e, l, e, l

По какой логике hello становится h e ll o?

Tim Biegeleisen 31.05.2018 15:54

> каждая подстрока содержит одинаковые конечные символы, ожидая, что на это ответят крутые потоки Java

Jorge.V 31.05.2018 15:55

Если есть несколько символов одного и того же значения, следующих друг за другом (рядом друг с другом в строке), то они становятся новой строкой. Следовательно, во втором примере две буквы L становятся двумя отдельными подстроками.

H_Lev1 31.05.2018 15:56

Не самый элегантный способ, но вы можете использовать регулярное выражение, например (?:(.)(\1))|.. Демо

The fourth bird 31.05.2018 16:02

@Thefourthbird Разрешены ли группы захвата в поисках Java? Я не мог заставить его работать. Может быть, тебе стоит опубликовать ответ.

Tim Biegeleisen 31.05.2018 16:08

@TimBiegeleisen Для группировки (.)(\1) используется не поисковая, а не захватывающая группа.

The fourth bird 31.05.2018 16:10

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

Tim Biegeleisen 31.05.2018 16:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
7
548
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

String input = "hello";
input = input.replaceAll("(\\w)(?!\\1)", "$1 ");
System.out.println(Arrays.toString(input.split(" ")));
input = "helel";
input = input.replaceAll("(\\w)(?!\\1)", "$1 ");
System.out.println(Arrays.toString(input.split(" ")));

[h, e, ll, o]
[h, e, l, e, l]

Демо

Хитрость здесь в том, что мы добавляем разделитель пробелов перед каждым символом, то есть нет, сразу за которым следует тот же символ. Таким образом, ll в hello остается смежным, потому что в этом случае утверждение опережающего просмотра потерпит неудачу.

Вы можете использовать Pattern и Matcher так:

String text = "hello";
String regex = "(.)\\1*";
Matcher matcher = Pattern.compile(regex).matcher(text);

List<String> result = new ArrayList<>();
while (matcher.find()) {
    result.add(matcher.group());
}
System.out.println(result);

Если вы используете Java 9+, вы можете использовать:

String text = "hello";
String regex = "(.)\\1*";
List<String> result = Pattern.compile(regex).matcher(text).results()
        .map(MatchResult::group)
        .collect(Collectors.toList());

Выходы

[h, e, ll, o]

Другие вопросы по теме