квантификатор повторения grepl

я пытаюсь проверить, содержит ли строка 2 или более значений даты

данная строка содержит четыре значения даты, но grepl возвращает FALSE

не могу заставить grepl обнаруживать все экземпляры даты в строке

> strng
[1] "SMART PRODUCTS 0.50 0.76 0.79 05/09/16 1000 1.02 1.02 27/06/16 17/06/11 27/06/16 0"
> grepl("([0-9][0-9]/[0-9][0-9]/[0-9][0-9]){1}", strng)
[1] TRUE
> grepl("([0-9][0-9]/[0-9][0-9]/[0-9][0-9]){2,}", strng)
[1] FALSE

person chiefr    schedule 01.11.2016    source источник
comment
Попробуйте grepl("(.*[0-9][0-9]/[0-9][0-9]/[0-9][0-9].*){2,}", x); ваш второй шаблон ищет два последовательных вхождения, например. grepl("([0-9][0-9]/[0-9][0-9]/[0-9][0-9]){2,}", "27/06/1617/06/11").   -  person nrussell    schedule 01.11.2016
comment
Вы можете посмотреть на функцию str_locate_all( ) в пакете stringr. и пакет stringi также предоставляет аналогичные функции.   -  person Dave2e    schedule 01.11.2016


Ответы (1)


Ваш первый шаблон ([0-9][0-9]/[0-9][0-9]/[0-9][0-9]){1} на самом деле может найти 4 вхождения: 05/09/16, 27/06/16, 17/06/11, 27/06/16.

Теперь, когда вы пытаетесь установить квантификатор ограничения для соответствия 2 или более вхождений, вся группа должна соответствовать шаблону 2 или более раз с натяжкой. Это то же самое, что количественное определение простого шаблона, такого как a: a{2,} найдет aaa в baaac, но не найдет соответствия в bacada.

Таким образом, вам нужно иметь возможность сопоставить что-либо до требуемого шаблона и поместить его в группу квантификации. Самый простой способ здесь — использовать ленивое сопоставление точек (.*?), которое будет соответствовать любым символам 0+, но как можно меньшему количеству):

(.*?[0-9][0-9]/[0-9][0-9]/[0-9][0-9]){2,}
 ^^^

См. демонстрацию регулярного выражения, которая не найдет соответствия в SMART PRODUCTS 0.50 0.76 0.79 17/06/11 0, но будет соответствовать рассматриваемой строке. .

ПРИМЕЧАНИЕ. Если вы используете регулярное выражение в grepl без perl=TRUE, это регулярное выражение TRE, и . будет соответствовать любому символу, включая символы разрыва строки. Если вы используете perl=TRUE, точка не будет соответствовать символам разрыва строки, вам нужно будет добавить (?s) в начале шаблона, чтобы обеспечить такое же поведение для точки.

person Wiktor Stribiżew    schedule 01.11.2016