Неожиданное совпадение регулярного выражения
Я ожидаю, что шаблон регулярного выражения 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 в терминах квантификаторов.)