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

Любые идеи?


person aL3xa    schedule 08.12.2011    source источник
comment
Не могли бы вы сопоставить строки, которые do начинаются с шаблона, а затем инвертировать логический результат от grepl?   -  person Joshua Ulrich    schedule 09.12.2011
comment
Конечно, но я бы хотел добавить туда еще кое-что! знак равно   -  person aL3xa    schedule 09.12.2011


Ответы (3)


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

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

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

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

person Dan    schedule 08.12.2011
comment
Вау, это было быстро и аккуратно. Спасибо! Мне придется ждать 7 минут, чтобы поставить галочку. знак равно - person aL3xa; 09.12.2011

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

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

По-видимому, вы можете отключить неявную жадность поиска с помощью специальных модификаторов подстановочных знаков 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).

person Paul McMurdie    schedule 08.04.2016

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

library(stringr)

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

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

Создано 13 января 2020 г. с помощью пакета reprex (v0.3.0)

person pasipasi    schedule 13.01.2020