Сложное регулярное выражение - PullRequest
3 голосов
/ 20 января 2011

Я бы использовал регулярное выражение в моей Java-программе, чтобы распознать некоторые особенности моих строк.У меня есть такой тип строки:

`-Author- написал (-hh -: - мм -)

Так, например, у меня естьстрока с:

Cecco написал (15:12)

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

hh and mm must be numbers

author hasn't any restrictions

I've to consider space between "has wrote" and (

Я не знаю, как я могуиспользовать регулярные выражения, вы могли бы мне помочь?

РЕДАКТИРОВАТЬ: я прилагаю свой фрагмент:

            String mRegex = "(\\s)+ has wrote \\((\\d\\d):(\\d\\d)\\)";
            Pattern mPattern = Pattern.compile(mRegex);

            String[] str = {
                "Cecco CQ has wrote (14:55)", //OK (matched)
                "yesterday you has wrote that I'm crazy", //NO (different text)
                "Simon has wrote (yesterday)", // NO (yesterday isn't numbers)
                "John has wrote (22:32)", //OK
                "James has wrote(22:11)", //NO (missed space between has wrote and ()
                "Tommy has wrote (xx:ss)" //NO (xx and ss aren't numbers)
            };

            for(String s : str) {
                Matcher mMatcher = mPattern.matcher(s);
                while (mMatcher.find()) {
                    System.out.println(mMatcher.group());
                }
            }

Ответы [ 3 ]

2 голосов
/ 20 января 2011

домашнее задание?

Что-то вроде:

(.+) has wrote \((\d\d):(\d\d)\)

Следует выполнить трюк

  • () - пометить группы для захвата (ввыше)
  • .+ - любые символы (вы сказали, что нет ограничений)
  • \d - любая цифра
  • \(\) экранировать парены как литералы вместо захватагруппа

использование:

Pattern p = Pattern.compile("(.+) has wrote \\((\\d\\d):(\\d\\d)\\)");

Matcher m = p.matcher("Gareth has wrote (12:00)");

if( m.matches()){
    System.out.println(m.group(1));
    System.out.println(m.group(2));
    System.out.println(m.group(3));
}

Чтобы справиться с необязательным (ЧЧ: мм) в конце, вам нужно начать использовать какое-то темное регулярное выражение вуду:

Pattern p = Pattern.compile("(.+) has wrote\\s?(?:\\((\\d\\d):(\\d\\d)\\))?");

Matcher m = p.matcher("Gareth has wrote (12:00)");

if( m.matches()){
    System.out.println(m.group(1));
    System.out.println(m.group(2));
    System.out.println(m.group(3));
}

m = p.matcher("Gareth has wrote");
if( m.matches()){       
    System.out.println(m.group(1));
    // m.group(2) == null since it didn't match anything
}

Новый неэкранированный шаблон:

(.+) has wrote\s?(?:\((\d\d):(\d\d)\))?
  • \s? опционально соответствует пробелу (в конце может не быть пробела, если нет группы (ЧЧ: мм)
  • (?: ... ) - группа без захвата, т. Е. Позволяет использовать для ввода ? после того, как это сделать необязательно

Я думаю, что @codinghorror имеет что-то, что можно сказатьрегулярное выражение

1 голос
/ 20 января 2011

Самый простой способ выяснить регулярные выражения - это использовать инструмент тестирования перед кодированием.
Я использую плагин eclipse из http://www.brosinski.com/regex/

Используя это, я получил следующий результат:

([a-zA-Z]*) has wrote \((\d\d):(\d\d)\)
Cecco has wrote (15:12)

Found 1 match(es):

start=0, end=23
Group(0) = Cecco has wrote (15:12)
Group(1) = Cecco
Group(2) = 15
Group(3) = 12

Отличный турориал по синтаксису регулярных выражений можно найти по адресу http://www.regular -expressions.info / tutorial.html

0 голосов
/ 20 января 2011

Ну, на тот случай, если вы не знали, Matcher имеет замечательную функцию, которая может выделять определенные группы или части шаблона, заключенные в (), Matcher.group(int). Например, если я хочу найти число между двумя точками с запятой, например:

: 22:

Я мог бы использовать регулярное выражение ":(\\d+):", чтобы сопоставить одну или несколько цифр между двумя точками с запятой, а затем я могу специально выбрать цифры с помощью:

Matcher.group(1)

И тогда это просто вопрос анализа строки в int. Как примечание, нумерация групп начинается с 1 . group (0) - это полное совпадение , поэтому Matcher.group (0) для предыдущего примера вернет: 22:

В вашем случае, я думаю, что биты регулярных выражений, которые вы должны учитывать,

  • "[A-Za-z]" для букв алфавита (возможно, вы могли бы также безопасно использовать "\\w", который сопоставляет символы алфавита, а также цифры и _).
  • "\\d" для цифр (1,2,3 ...)
  • "+" для указания того, хотите ли вы один или несколько из предыдущего символа или группы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...