R-regex: строки соответствия не начинаются с шаблона

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

> 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

Любые идеи?

Ответ 1

Да. Поместите нулевую ширину влево/вправо/в другую сторону. Это должно дать вам следующее:

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

который, как я думаю, вам нужен.

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

Ответ 2

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

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

Очевидно, вы можете отключить скрытую жадность поиска с конкретными первыми модификаторами подстановки

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

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)

"abcdefghijklm_nopqrstuvwxyz"

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