Как разбить строку между буквами и цифрами (или между цифрами и буквами)?
Я пытаюсь выработать способ разделения строки в java, которая следует за шаблоном:
String a = "123abc345def";
Результаты этого должны быть следующими:
x[0] = "123";
x[1] = "abc";
x[2] = "345";
x[3] = "def";
Однако я полностью зациклен на том, как я могу это достичь. Пожалуйста, кто-нибудь может мне помочь? Я попытался найти в Интернете аналогичную проблему, однако очень сложно правильно ее правильно найти в поиске.
Обратите внимание: Количество букв и цифр может меняться (например, может быть строка типа "1234a5bcdef" )
Ответы
Ответ 1
Вы можете попытаться разделить на (?<=\D)(?=\d)|(?<=\d)(?=\D)
, например:
str.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
Он сопоставляет позиции между числом и не числом (в любом порядке).
-
(?<=\D)(?=\d)
- соответствует позиции между не цифрой (\D
) и цифрой (\d
) -
(?<=\d)(?=\D)
- соответствует позиции между цифрой и не цифрой.
Ответ 2
Как насчет:
private List<String> Parse(String str) {
List<String> output = new ArrayList<String>();
Matcher match = Pattern.compile("[0-9]+|[a-z]+|[A-Z]+").matcher(str);
while (match.find()) {
output.add(match.group());
}
return output;
}
Ответ 3
Вы можете попробовать следующее:
Pattern p = Pattern.compile("[a-z]+|\\d+");
Matcher m = p.matcher("123abc345def");
ArrayList<String> allMatches = new ArrayList<>();
while (m.find()) {
allMatches.add(m.group());
}
Результат (allMatches) будет:
["123", "abc", "345", "def"]
Ответ 4
Используйте два разных шаблона: [0-9]*
и [a-zA-Z]*
и дважды разделяйте их по каждому из них.
Ответ 5
Если вы ищете решение без использования функциональности Java String
(т.е. split
, match
и т.д.), то следующее должно помочь:
List<String> splitString(String string) {
List<String> list = new ArrayList<String>();
String token = "";
char curr;
for (int e = 0; e < string.length() + 1; e++) {
if (e == 0)
curr = string.charAt(0);
else {
curr = string.charAt(--e);
}
if (isNumber(curr)) {
while (e < string.length() && isNumber(string.charAt(e))) {
token += string.charAt(e++);
}
list.add(token);
token = "";
} else {
while (e < string.length() && !isNumber(string.charAt(e))) {
token += string.charAt(e++);
}
list.add(token);
token = "";
}
}
return list;
}
boolean isNumber(char c) {
return c >= '0' && c <= '9';
}
Это решение будет разделять числа и слова, где "слова" - это строки, которые не содержат чисел. Однако, если вам нравится иметь только "слова", содержащие английские буквы, вы можете легко изменить его, добавив больше условий (например, вызов метода isNumber
) в зависимости от ваших требований (например, вы можете пропустить слова, содержащие неанглийские буквы). Также обратите внимание, что метод splitString
возвращает ArrayList
, который позже может быть преобразован в массив String
.
Ответ 6
Не использовал Java целую вечность, поэтому просто какой-то псевдо-код, который должен помочь вам начать (быстрее для меня, чем вскрыть все:)).
string a = "123abc345def";
string[] result;
while(a.Length > 0)
{
string part;
if((part = a.Match(/\d+/)).Length) // match digits
;
else if((part = a.Match(/\a+/)).Length) // match letters
;
else
break; // something invalid - neither digit nor letter
result.append(part);
a = a.SubStr(part.Length - 1); // remove the part we've found
}
Ответ 7
Я делал такие вещи для критически важного кода. Как и каждая часть секунды, я рассчитываю, что мне нужно обработать 180 тыс. Записей за незаметное количество времени. Таким образом, я пропустил регулярное выражение и полностью разделился и разрешил встроенную обработку каждого элемента (хотя добавление их к ArrayList<String>
было бы в порядке). Если вы хотите сделать это точно, но нужно, чтобы это было примерно как 20x быстрее...
void parseGroups(String text) {
int last = 0;
int state = 0;
for (int i = 0, s = text.length(); i < s; i++) {
switch (text.charAt(i)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (state == 2) {
processElement(text.substring(last, i));
last = i;
}
state = 1;
break;
default:
if (state == 1) {
processElement(text.substring(last, i));
last = i;
}
state = 2;
break;
}
}
processElement(text.substring(last));
}
Ответ 8
Разве это не "d+|d+"
делать работу вместо громоздкой: "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"
?