R-регулярное выражение: сопоставление строк, не начинающихся с шаблона

Я хотел бы использовать регулярное выражение, чтобы увидеть, если строка не начинается с определенного шаблона. Пока я могу использовать: [^ Чтобы занести в черный список определенные символы, я не могу понять, как занести в черный список шаблон.

> grepl("^[^abc].+$", "foo")
[1] TRUE
> grepl("^[^abc].+$", "afoo")
[1] FALSE

Я хотел бы сделать что-то вроде grepl("^[^(abc)].+$", "afoo") и получить TRUEто есть совпадать, если строка не начинается с abc последовательность.

Обратите внимание, что я знаю об этом посте, и я также пытался использовать perl = TRUE, но безуспешно:

> grepl("^((?!hede).)*$", "hede", perl = TRUE)
[1] FALSE
> grepl("^((?!hede).)*$", "foohede", perl = TRUE)
[1] FALSE

Есть идеи?

2 ответа

Решение

Да уж. Положите заглядывание нулевой ширины / снаружи / другие паренсы. Это должно дать вам это:

> grepl("^(?!hede).*$", "hede", perl = TRUE)
[1] FALSE
> grepl("^(?!hede).*$", "foohede", perl = TRUE)
[1] TRUE

что я думаю, что вы хотите.

С другой стороны, если вы хотите захватить всю строку, ^(?!hede)(.*)$ а также ^((?!hede).*)$ оба эквивалентны и приемлемы.

Сейчас (годы спустя) есть еще одна возможность с stringr пакет.

library(stringr)

str_detect("dsadsf", "^abc", negate = TRUE)
#> [1] TRUE

str_detect("abcff", "^abc", negate = TRUE)
#> [1] FALSE

Создано 13.01.2020 пакетом REPEX (v0.3.0)

Я застрял в следующем особом случае, поэтому я решил поделиться...

Что если есть несколько экземпляров регулярного выражения, но вам все еще нужен только первый сегмент?

По-видимому, вы можете отключить неявную жадность поиска с помощью специальных подстановочных символов perl

Предположим, что строка, которую я хотел обработать, была

myExampleString = paste0(c(letters[1:13], "_", letters[14:26], "__",
                           LETTERS[1:13], "_", LETTERS[14:26], "__",
                           "laksjdl", "_", "lakdjlfalsjdf"),
                         collapse = "")
myExampleString

"Abcdefghijklm_nopqrstuvwxyz__ABCDEFGHIJKLM_NOPQRSTUVWXYZ__laksjdl_lakdjlfalsjd"

и что я хотел только первый сегмент перед первым "__", Я не могу просто искать на "_", потому что в этом примере строка допускается без разделителя.

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

gsub("^(.+(?=__)).*$", "\\1", myExampleString, perl = TRUE)

"Abcdefghijklm_nopqrstuvwxyz__ABCDEFGHIJKLM_NOPQRSTUVWXYZ"

Но это работает

gsub("^(.+?(?=__)).*$", "\\1", myExampleString, perl = TRUE)

"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ"

Разница в том, что жадный модификатор "?" после подстановочного знака ".+"в (perl) регулярном выражении.

Другие вопросы по тегам