Как разбить строку между буквами и цифрами (или между цифрами и буквами)? - PullRequest
48 голосов
/ 25 ноября 2011

Я пытаюсь найти способ разделения строки в java, которая выглядит следующим образом:

String a = "123abc345def";

Результат должен быть следующим:

x[0] = "123";
x[1] = "abc";
x[2] = "345";
x[3] = "def";

Однако я совершенно не уверен, как мне этого достичь.Пожалуйста, кто-нибудь может мне помочь?Я пытался найти в Интернете аналогичную проблему, однако очень трудно правильно ее сформулировать при поиске.

Обратите внимание: Количество букв и цифр может быть разнымстрока вроде так '1234a5bcdef')

Ответы [ 8 ]

85 голосов
/ 25 ноября 2011

Вы можете попробовать разделить на (?<=\D)(?=\d)|(?<=\d)(?=\D), например:

str.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");

Соответствует позициям между числом и не числом (в любом порядке).

  • (?<=\D)(?=\d) - соответствует позиции между нецифровой (\D) и цифрой (\d)
  • (?<=\d)(?=\D) - соответствует позиции между цифрой и нецифровой.
9 голосов
/ 25 ноября 2011

Как насчет:

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;
}
7 голосов
/ 17 декабря 2015

Вы можете попробовать это:

Pattern p = Pattern.compile("[a-z]+|\\d+");
Matcher m = p.matcher("123abc345def");
ArrayList<String> allMatches = new ArrayList<>();
while (m.find()) {
    allMatches.add(m.group());
}

Результат (все совпадения) будет:

["123", "abc", "345", "def"]
3 голосов
/ 25 ноября 2011

Используйте два разных шаблона: [0-9]* и [a-zA-Z]* и делите их по два на каждый.

2 голосов
/ 06 декабря 2016

Если вы ищете решение без использования функциональных возможностей 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.

1 голос
/ 05 января 2017

Я делал подобные вещи для критически важного кода.Как и каждая доля секунды, потому что мне нужно обработать 180 тыс. Записей за незаметное время.Поэтому я пропустил регулярное выражение и разделил его полностью и разрешил встроенную обработку каждого элемента (хотя их добавление в ArrayList<String> было бы хорошо)Если вы хотите сделать именно это, но хотите, чтобы это было примерно в 20 раз быстрее ...

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));
}
1 голос
/ 25 ноября 2011

Не использовал 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
 }
0 голосов
/ 03 июня 2019

Не правда ли? "d+|D+" делай работу вместо громоздкой "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...