Ответ 1
В настоящее время (включая Java 8) это можно сделать с помощью split()
, но в реальном мире этот подход не используется, поскольку он выглядит так, как будто он основан на ошибке (look-behind в Java должен иметь очевидная максимальная длина, но в этом решении используется \w+
, который не соблюдает это ограничение). Вместо этого используйте классы Pattern
и Matcher
, чтобы избежать чрезмерного компрометации thins и обслуживания ада, поскольку это поведение может измениться в следующих версиях Java или в Java-подобных средах, таких как Android.
Это то, что вы ищете?
(вы можете заменить \\w
на \\S
, чтобы включить все непространственные символы, но в этом примере я оставлю \\w
, так как легче читать регулярное выражение с помощью \\w\\s
, а затем \\S\\s
)суб >
String input = "one two three four five six seven";
String[] pairs = input.split("(?<!\\G\\w+)\\s");
System.out.println(Arrays.toString(pairs));
выход:
[one two, three four, five six, seven]
\G
- предыдущее совпадение, (?<!regex)
- отрицательный lookbehind.
В split
мы пытаемся
- найти пробелы →
\\S
- которые не прогнозируются →
(?<!negativeLookBehind)
- некоторым словом →
\\w+
- с ранее сопоставленным (пробелом) →
\\G
- перед этим →
\\G\\w+
.
Только путаница, с которой я столкнулся, заключалась в том, как она будет работать для первого пространства, так как мы хотим, чтобы это пространство было проигнорировано. Важная информация заключается в том, что \\G
при запуске соответствует началу строки ^
.
Итак, перед тем как первое итерационное регулярное выражение будет выглядеть как (?<!^\\w+)
, а так как первое пространство do имеет ^\\w+
раньше, оно не может быть совпадением для split. Следующий пробел не будет иметь этой проблемы, поэтому он будет согласован, и информация об этом (например, его позиция в input
String) будет сохранена в \\G
и использована позже в следующем негативном образе.
Итак, для 3-го пространства регулярное выражение будет проверять, есть ли ранее сопоставленное пространство \\G
и слово \\w+
перед ним. Поскольку результат этого теста будет положительным, отрицательный внешний вид не примет его, поэтому это пространство не будет согласовано, но 4-е пространство не будет иметь эту проблему, потому что пространство до него не будет таким же, как в \\G
(оно будет иметь разную позицию в input
String).
Также, если кто-то хочет разделить на let, скажем, каждое третье пространство, вы можете использовать эту форму (на основе @maybeWeCouldStealAVan ответ, который был удален, когда я разместил этот фрагмент ответа)
input.split("(?<=\\G\\w{1,100}\\s\\w{1,100}\\s\\w{1,100})\\s")
Вместо 100 вы можете использовать какое-то большее значение, которое будет по меньшей мере размером с длиной самого длинного слова в String.
Я только заметил, что мы можем использовать +
вместо {1,maxWordLength}
, если мы хотим разделить с каждым нечетным числом, как каждый третий, пятый, седьмой, например
String data = "0,0,1,2,4,5,3,4,6,1,3,3,4,5,1,1";
String[] array = data.split("(?<=\\G\\d+,\\d+,\\d+,\\d+,\\d+),");//every 5th comma