Этот RegEx фиксирует неправильное количество групп - PullRequest
2 голосов
/ 18 февраля 2010

Я должен проанализировать строку и захватить некоторые значения:

FREQ = НЕДЕЛЬНЫЙ; WKST = МО; BYDAY = 2TU, 2WE

Я хочу захватить 2 группы:

grp 1: 2, 2
grp 2: TU, WE

Числа представляют интервалы. ТУ, МЫ представляет будни. Мне нужны оба.

Я использую этот код:

private final static java.util.regex.Pattern regBYDAY = java.util.regex.Pattern.compile(".*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*");

String rrule = "FREQ=WEEKLY;WKST=MO;BYDAY=2TU,2WE";
java.util.regex.Matcher result = regBYDAY.matcher(rrule);
if (result.matches())
{
    int grpCount = result.groupCount();
    for (int i = 1; i < grpCount; i++)
    {
        String g = result.group(i);
        ...
    }
}

grpCount == 2 - почему? Если я правильно прочитал документацию Java (то немного), я должен получить 5? 0 = все выражение, 1,2,3,4 = мои снимки 2,2, TU и WE.

result.group (1) == "2";

Я программист на C # с очень небольшим опытом работы с Java, поэтому я протестировал RegEx в "Инструментальных средствах регулярных выражений" - отличной программе на C # для тестирования RegEx. Там мой RegEx работает нормально.

https://code.msdn.microsoft.com/RegexWorkbench

RegExWB:

.*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*

Matching:
FREQ=WEEKLY;WKST=MO;BYDAY=22TU,-2WE,+223FR
  1 => 22
  1 => -2
  1 => +223
  2 => TU
  2 => WE
  2 => FR

Ответы [ 3 ]

1 голос
/ 18 февраля 2010

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

final Pattern re1 = Pattern.compile(".*;BYDAY=(.*)");
final Pattern re2 = Pattern.compile("(?:([+-]?[0-9]*)([A-Z]{2}),?)");

final Matcher matcher1 = re1.matcher(rrule);
if ( matcher1.matches() ) {
    final String group1 = matcher1.group(1);
    Matcher matcher2 = re2.matcher(group1);
    while(matcher2.find()) {
        System.out.println("group: " + matcher2.group(1) + " " +
                    matcher2.group(2));
    }
}
1 голос
/ 19 февраля 2010

Ваше регулярное выражение работает в Java так же, как и в C #;просто в Java вы можете получить доступ только к финальному захвату для каждой группы.На самом деле .NET является одним из двух известных мне регулярных выражений, которые позволяют вам получать промежуточные записи (Perl 6 - другой).

Это, вероятно, самый простой способ сделать то, что вы хотите в Java:

String s= "FREQ=WEEKLY;WKST=MO;BYDAY=22TU,-2WE,+223FR";
Pattern p = Pattern.compile("(?:;BYDAY=|,)([+-]?[0-9]+)([A-Z]{2})");
Matcher m = p.matcher(s);
while (m.find())
{
  System.out.printf("Interval: %5s, Day of Week: %s%n",
                    m.group(1), m.group(2));
}

Вот эквивалентный код C #, если вам интересно:

string s = "FREQ=WEEKLY;WKST=MO;BYDAY=22TU,-2WE,+223FR";
Regex r = new Regex(@"(?:;BYDAY=|,)([+-]?[0-9]+)([A-Z]{2})");
foreach (Match m in r.Matches(s))
{
  Console.WriteLine("Interval: {0,5}, Day of Week: {1}",
                    m.Groups[1], m.Groups[2]);
}
0 голосов
/ 18 февраля 2010

Я немного заржавел, но я предлагаю "предостережения".Прежде всего, regexp (s) входят в различные диалекты.Об этом есть фантастическая книга О'Рейли, но есть вероятность, что ваша утилита C # применяет немного другие правила.

В качестве примера я использовал похожий (но другой инструмент )и обнаружил, что он по-разному разбирает вещи ...

Прежде всего он отклонил ваше регулярное выражение (может быть, опечатку?), начальный "*" не имеет смысла, если вы не поставите точку (.) передэтогоВот так:

.*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*

Теперь он был принят, но он "соответствовал" только части 2 / WE и "пропустил" пару 2 / TU.

(предлагаю прочитатьо жадном и не жадном сопоставлении, чтобы понять это немного лучше.

Поэтому я обновил ваш шаблон следующим образом:

.*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?),(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*

И теперь он работает и правильно захватывает 2, TU, 2 иМЫ.

Может, это поможет?

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