Неожиданное совпадение регулярного выражения

Я ожидаю, что шаблон регулярного выражения ab{,2}c будет соответствовать только с a, за которым следуют 0, 1 или 2 b s, а затем c.

Он работает именно так на многих языках, например Python. Однако в R:

grepl("ab{,2}c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
# [1]  TRUE  TRUE  TRUE  TRUE FALSE

Я удивлен 4-м TRUE. В ?regex я могу читать:

{n,m} Предыдущий элемент сопоставляется не менее n раз, но не более чем m раз.

Итак, я согласен, что {,2} должен быть записан {0,2} как допустимый шаблон (в отличие от Python, где явно указано состояние docs, опускающее n, указывает нижнюю границу нуля).

Но при использовании {,2} следует выбросить ошибку, а не возвращать вводящие в заблуждение соответствия! Я что-то пропустил или должен быть сообщен как ошибка?

Ответ 1

Поведение с {,2} не ожидается, это ошибка. Если вы посмотрите на исходный код TRE, tre_parse_bound method, вы увидите, что значение переменной min установлено на -1, прежде чем двигатель попытается инициализировать минимальную границу. Кажется, что число "повторов" в случае отсутствия минимального значения в кванторе - это максимальное значение + 1 (как если бы число повторений равно max - min = max - (-1) = max+1).

Итак, a{,} соответствует одному вхождению a. То же, что a{, } или a{ , }. См. R demo, только abc соответствует ab{,}c:

grepl("ab{,}c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
grepl("ab{, }c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
grepl("ab{ ,   }c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
## => [1] FALSE  TRUE FALSE FALSE FALSE

Ответ 2

Как дополнение:

vec1 = c('','a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa','aaaaaaa')

grep("^a{,1}$", vec1, value = T) # seems to "become" ^a{1}$
grep("^a{,2}$", vec1, value = T) # seems to "become" ^a{0,3}$
grep("^a{,3}$", vec1, value = T) # seems to "become" ^a{0,4}$
grep("^a{,4}$", vec1, value = T) # seems to "become" ^a{0,5}$

Ответ 3

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

Обновление: после ответа Wiktor Stribiżew и обратной связи кажется, что поведение является категорией как ошибка.

Оригинал: Синтаксис, который вы используете, просто не поддерживается в R (при условии, что он работает по умолчанию). Вот почему вы получаете неожиданные результаты.

  • Поддерживаемый синтаксис - {n, m}, как указано в документации. Таким образом, вам нужно указать обе границы, например. {0,2}, который вернет правильный результат.
  • Синтаксис {, m}, с другой стороны, отсутствует в документации для регулярного выражения, что тихо указывает, что оно не поддерживается.

Если вы хотите изучить различия в синтаксисе, я бы рекомендовал взглянуть на страницу сравнения regular-expressions.info. (В этом случае вам нужно сравнить Python и R в терминах квантификаторов.)