Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз" / 8 сообщений из 8, страница 1 из 1
07.09.2013, 15:31:45
    #38389990
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
Здравствуйте.
В документации читаем: Differences Among Greedy, Reluctant, and Possessive Quantifiers

Greedy quantifiers are considered "greedy" because they force the matcher to read in, or eat,
the entire input string prior to attempting the first match . If the first match attempt
(the entire input string) fails, the matcher backs off the input string by one character and
tries again
, repeating the process until a match is found or there are no more characters
left to back off from. Depending on the quantifier used in the expression, the last thing
it will try matching against is 1 or 0 characters.

The reluctant quantifiers, however, take the opposite approach: They start at the beginning
of the input string, then reluctantly eat one character at a time looking for a match.
The last thing they try is the entire input string.

Решил проверить:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
import java.io.*;
import java.util.regex.*;

class RegexQuantTest {
  static Console c = System.console();
  static String text, patt;
  static Matcher m;
  public static void main(String[] args) {
    while(true) {
      text = c.readLine("%s", "TEXT: ");
      System.out.println(     "      0123456789012345");
      patt = c.readLine("%s", "WHAT: ");

      m = Pattern.compile(patt).matcher(text);

      while(m.find()) System.out.println( "found at pos #"+m.start()+", substring="+m.group()+", end at pos #"+m.end() );
      System.out.println("");
    }
  }
}



Запускаю, при этом ввожу одну и ту же строку:
Код: plaintext
1.
2.
abababababababab
0123456789012345 // счётчик смещений от начала
и шаблоны: (ab), (aba), (abab), (ababa), (ababab) - сначала с квантификатором жадного, а затем - "неохотного" (или какой там устоявшийся перевод reluctant) поведения.

Результат: не могу понять поведение matcher'a в режиме greedy на шаблонах с не чётной длиной
примеры
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
TEXT: abababababababab
      0123456789012345
WHAT: (ab)+ // greedy
found at pos #0, substring=abababababababab, end at pos #16 
// здесь всё понятно: хапнули всю строку сразу, посмотрели сколько раз входит в неё шаблон "ab" 
// видим, что входит как минимум 1 раз ==> выкинули сразу всю строку

TEXT: abababababababab
      0123456789012345
WHAT: (ab)+? // reluctant
found at pos #0, substring=ab, end at pos #2
found at pos #2, substring=ab, end at pos #4
found at pos #4, substring=ab, end at pos #6
found at pos #6, substring=ab, end at pos #8
found at pos #8, substring=ab, end at pos #10
found at pos #10, substring=ab, end at pos #12
found at pos #12, substring=ab, end at pos #14
found at pos #14, substring=ab, end at pos #16
// здесь тоже всё понятно, т.к. начали скармливать matcher'у начиная с первого символа

TEXT: abababababababab
      0123456789012345
WHAT: (aba)+ // greedy
found at pos #0, substring=aba, end at pos #3
found at pos #4, substring=aba, end at pos #7
found at pos #8, substring=aba, end at pos #11
found at pos #12, substring=aba, end at pos #15
// А вот здесь понять не могу: matcher съел сначала ВСЮ строку, как в примере выше, и...
// что помешало ему СРАЗУ определить, что шаблон 'aba' входит в неё также как минимум 1 раз
// и СРАЗУ выдать результат в том виде, как при шаблоне '(ab)+', а именно:
// found at pos #0, substring=abababababababab, end at pos #16 

TEXT: abababababababab
      0123456789012345
WHAT: (aba)+?
found at pos #0, substring=aba, end at pos #3
found at pos #4, substring=aba, end at pos #7
found at pos #8, substring=aba, end at pos #11
found at pos #12, substring=aba, end at pos #15


// дальше всё повторяется: для шаблонов с чётной длиной matcher 
// в greedy-режиме работает объяснимо (для меня, по кр. мере),
// а для шаблонов с нечётной - нет.

TEXT: abababababababab
      0123456789012345
WHAT: (abab)+
found at pos #0, substring=abababababababab, end at pos #16

TEXT: abababababababab
      0123456789012345
WHAT: (abab)+?
found at pos #0, substring=abab, end at pos #4
found at pos #4, substring=abab, end at pos #8
found at pos #8, substring=abab, end at pos #12
found at pos #12, substring=abab, end at pos #16


TEXT: abababababababab
      0123456789012345
WHAT: (ababa)+
found at pos #0, substring=ababa, end at pos #5
found at pos #6, substring=ababa, end at pos #11

TEXT: abababababababab
      0123456789012345
WHAT: (ababa)+?
found at pos #0, substring=ababa, end at pos #5
found at pos #6, substring=ababa, end at pos #11


TEXT: abababababababab
      0123456789012345
WHAT: (ababab)+
found at pos #0, substring=abababababab, end at pos #12

TEXT: abababababababab
      0123456789012345
WHAT: (ababab)+?
found at pos #0, substring=ababab, end at pos #6
found at pos #6, substring=ababab, end at pos #12
...
Рейтинг: 0 / 0
07.09.2013, 19:41:31
    #38390087
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
ozzmosis,

Два квантификатора подряд не ставят:
Код: java
1.
2.
3.
4.
5.
6.
7.
(aba)+
(ababa)+

// либо:

(aba)?
(ababa)?
...
Рейтинг: 0 / 0
07.09.2013, 19:56:24
    #38390089
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
UsmanДва квантификатора подряд не ставятХм... а как же дока ?At first glance it may appear that the quantifiers X?, X ?? and X ?+ do exactly the same thing, since they all promise to match "X, once or not at all".
...
Рейтинг: 0 / 0
07.09.2013, 20:26:50
    #38390100
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
ozzmosisХм... а как же дока ?Стоп. Вру (сорри). Давно не работал с регэспами. Подзабыл. :-Pozzmosisне могу понять поведение matcher'a в режиме greedy на шаблонах с не чётной длинойПопытаюсь объяснить на Ваших же примерах:

(ababa)+?
ababa b ababa babab (по-одному разу - в итоге замэтчились две группы)

abababababab abab
(ababab)+ (подряд (одна группа) - захватил (жадно) за один раз сразу две шаблонные подстроки)

ababab ababab abab
(ababab)+? (по-одному разу - в итоге две группы)
...
Рейтинг: 0 / 0
07.09.2013, 20:50:23
    #38390107
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
UsmanПопытаюсь объяснить на Ваших же примерахУвы, но я всё равно не понял, как этот самый матчер работает для случая жадного квантификатора :(
Вот описание доки:Greedy quantifiers are considered "greedy" because they force the matcher to read in, or eat,
the entire
input string prior to attempting the first match. If the first match attempt
(the entire input string) fails, the matcher backs off the input string by one character and
tries again , repeating the process until a match is found or there are no more characters
left to back off from.
Вот input-строка: abababababababab и шаблон-группа: aba.
Матчер должен сначала хапнуть всю строку и затем проверить, не содержится ли в ней хотя бы один раз шаблон. Ответ будет очевиден: да, содержится.
Почему тогда матчер принимается дальше искать в этой строке (как будто бы "If the first match attempt (the entire input string) fails"), вместо того чтобы сразу выдать результат ?
...
Рейтинг: 0 / 0
07.09.2013, 21:01:30
    #38390113
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
ozzmosisУвы, но я всё равно не понял, как этот самый матчер работает для случая жадного квантификатора :( (ababa)+ == (можно записать как) (ababa){1,}
{1,} - означает, что подстрока (шаблонная группа) должна встретиться как минимум один раз, либо "сколько возможно" раз подряд.
В результате получаем несколько подряд ( слитно! ) идущих подстрок (шаблона) -- засчитывается как одно совпадение (match).
В этом суть жадности.
...
Рейтинг: 0 / 0
07.09.2013, 21:56:42
    #38390140
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
UsmanozzmosisУвы, но я всё равно не понял, как этот самый матчер работает для случая жадного квантификатора :( (ababa)+ == (можно записать как) (ababa){1,}
{1,} - означает, что подстрока (шаблонная группа) должна встретиться как минимум один раз, либо "сколько возможно" раз подряд.
В результате получаем несколько подряд ( слитно! ) идущих подстрок (шаблона) -- засчитывается как одно совпадение (match).
В этом суть жадности."Как минимум один раз" - это условие точно становится истинным после первого обнаружения шаблона "ababa" в input-строке.
Я главного не понимаю: что ему, матчеру, помешало немедленно остановиться, когда он анализировал input-строку на наличие этой группы и нашёл её там ? Почему он не выкинул для этого варианта то же самое, что и для (abab)+, а пошёл дальше искать и в результате выдал:
Код: plaintext
1.
2.
3.
4.
5.
TEXT: abababababababab
      0123456789012345
WHAT: (ababa)+
found at pos #0, substring=ababa, end at pos #5
found at pos #6, substring=ababa, end at pos #11
...
Рейтинг: 0 / 0
07.09.2013, 22:43:07
    #38390157
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз"
ozzmosisЯ главного не понимаю: что ему, матчеру, помешало немедленно остановиться, когда он анализировал input-строку на наличие этой группы и нашёл её там ? Почему он не выкинул для этого варианта то же самое, что и для (abab)+, а пошёл дальше искать
Код: java
1.
2.
3.
while(m.find()) {
  ...
}
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / regex, поиск группы с greedy квантиф-ром "+": результаты понятны как-то "через раз" / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]