Java - Извлечение строк с помощью Regex - PullRequest
16 голосов
/ 04 августа 2009

У меня есть эта строка

String myString ="A~BC~FGH~~zuzy|XX~ 1234~ ~~ABC~01/01/2010 06:30~BCD~01/01/2011 07:45";

и мне нужно извлечь эти 3 подстроки
1234
06: 30
07: 45

Если я использую это регулярное выражение \\ d {2} \: \\ d {2}, я смогу извлечь только первый час 06: 30

Pattern depArrHours = Pattern.compile("\\d{2}\\:\\d{2}");
Matcher matcher = depArrHours.matcher(myString);
String firstHour = matcher.group(0);
String secondHour = matcher.group(1); (IndexOutOfBoundException no Group 1)

matcher.group (1) выдает исключение.
Также я не знаю, как извлечь 1234. Эта строка может измениться, но она всегда идет после 'XX ~'
У вас есть идея, как сопоставить эти строки с выражениями регулярных выражений?

UPDATE

Благодаря предложению Адама у меня теперь есть это регулярное выражение, соответствующее моей строке

Pattern p = Pattern.compile(".*XX~ (\\d{3,4}).*(\\d{1,2}:\\d{2}).*(\\d{1,2}:\\d{2})";

Я сопоставляю число и 2 часа с matcher.group (1); matcher.group (2); matcher.group (3); * +1029 *

1 Ответ

41 голосов
/ 04 августа 2009

Функция matcher.group() предполагает получение одного целочисленного аргумента: индекс группы захвата, начиная с 1. Индекс 0 является специальным, что означает «полное соответствие». Группа захвата создается с использованием пары круглых скобок "(...)". Все, что находится в скобках, является захватом. Группы нумеруются слева направо (опять же, начиная с 1), открывая круглые скобки (что означает, что группы могут перекрываться). Поскольку в вашем регулярном выражении нет скобок, не может быть группы 1.

Javadoc в классе Pattern охватывает синтаксис регулярного выражения.

Если вы ищете шаблон, который может повторяться несколько раз, вы можете использовать Matcher. find () несколько раз, пока он не вернет false. Matcher.group(0) один раз на каждой итерации будет возвращать то, что соответствовало этому времени.

Если вы хотите создать одно большое регулярное выражение, которое совпадает со всем сразу (что, я считаю, то, что вы хотите), то вокруг каждого из трех наборов вещей, которые вы хотите захватить, поместите набор скобок для захвата, используйте Matcher.match() и затем Matcher.group(n), где n равно 1, 2 и 3 соответственно. Конечно, Matcher.match() также может возвращать false, в этом случае шаблон не совпадает, и вы не можете получить ни одну из групп.

В вашем примере вы, вероятно, захотите сделать так, чтобы оно совпадало с каким-либо предыдущим текстом, затем начинайте группу захвата, сопоставляйте цифры, заканчивайте группу захвата и т. Д. Я не знаю достаточно о вашем точном вводе формат, но вот пример.

Допустим, у меня были строки вида:

Eat 12 carrots at 12:30
Take 3 pills at 01:15

И я хотел извлечь количество и время. Мое регулярное выражение будет выглядеть примерно так:

"\w+ (\d+) [\w ]+ (\d{1,2}:\d{2})"

Код будет выглядеть примерно так:

Pattern p = Pattern.compile("\\w+ (\\d+) [\\w ]+ (\\d{2}:\\d{2})");
Matcher m = p.matcher(oneline);
if(m.matches()) {
    System.out.println("The quantity is " + m.group(1));
    System.out.println("The time is " + m.group(2));
}

Регулярное выражение означает «строку, содержащую слово, пробел, одну или несколько цифр (которые захвачены в группе 1), пробел, набор слов и пробелов, заканчивающихся пробелом, за которыми следует время (захваченное в группе 2, и время предполагает, что час всегда дополняется 0 до 2 цифр.) Я бы привел более близкий пример к тому, что вы ищете, но описание возможного ввода немного расплывчато.

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