Как мне работать со специальными символами, такими как \ ^ $.? * | + () [{В моем регулярном выражении?

Я хочу сопоставить специальный символ регулярного выражения, \^$.?*|+()[{. Я пытался:

x <- "a[b"
grepl("[", x)
## Error: invalid regular expression '[', reason 'Missing ']''

(Эквивалентно stringr::str_detect(x, "[") или stringi::stri_detect_regex(x, "[").)

Удвоение значения, чтобы избежать этого, не работает:

grepl("[[", x)
## Error: invalid regular expression '[[', reason 'Missing ']''

Также не используется обратная косая черта:

grepl("\[", x)
## Error: '\[' is an unrecognized escape in character string starting ""\["

Как сопоставить специальные символы?


Некоторые особые случаи этого в старых и достаточно хорошо написанных вопросах, чтобы было нахально закрывать их как дубликаты:
Экранированные периоды в регулярных выражениях R
Как избежать вопросительного знака в R?
экранирующая труба (|) в регулярном выражении


person Richie Cotton    schedule 31.12.2014    source источник


Ответы (2)


Побег с двойной обратной косой чертой

R обрабатывает обратную косую черту как escape-значения для символьных констант. (... как и регулярные выражения. Отсюда необходимость в двух обратных косых чертах при передаче символьного аргумента для шаблона. Первый на самом деле не является символом, а, скорее, он превращает второй в символ.) Вы можете видеть как они обрабатываются с помощью cat.

y <- "double quote: \", tab: \t, newline: \n, unicode point: \u20AC"
print(y)
## [1] "double quote: \", tab: \t, newline: \n, unicode point: €"
cat(y)
## double quote: ", tab:    , newline: 
## , unicode point: €

Дополнительная литература: Преобразование обратной косой черты с помощью обратной косой черты в R приводит к получению 2 обратных косых черт в строке, а не 1

Чтобы использовать специальные символы в регулярном выражении, самый простой способ - это экранировать их с помощью обратной косой черты, но, как отмечалось выше, необходимо экранировать саму обратную косую черту.

grepl("\\[", "a[b")
## [1] TRUE

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

grepl("\\\\", c("a\\b", "a\nb"))
## [1]  TRUE FALSE

Пакет rebus содержит константы для каждого из специальных символов, чтобы избежать ошибок при вводе косой черты.

library(rebus)
OPEN_BRACKET
## [1] "\\["
BACKSLASH
## [1] "\\\\"

Дополнительные примеры см .:

?SpecialCharacters

Решить вашу проблему можно так:

library(rebus)
grepl(OPEN_BRACKET, "a[b")

Сформируйте класс персонажей

Вы также можете заключить специальные символы в квадратные скобки, чтобы сформировать класс символов.

grepl("[?]", "a?b")
## [1] TRUE

Два специальных символа имеют особое значение внутри классов символов: \ и ^.

Обратную косую черту по-прежнему нужно экранировать, даже если она находится внутри класса символов.

grepl("[\\\\]", c("a\\b", "a\nb"))
## [1]  TRUE FALSE

Символ каретки нужно экранировать только в том случае, если он стоит сразу после открывающей квадратной скобки.

grepl("[ ^]", "a^b")  # matches spaces as well.
## [1] TRUE
grepl("[\\^]", "a^b") 
## [1] TRUE

rebus также позволяет вам формировать класс персонажей.

char_class("?")
## <regex> [?]

Используйте уже существующий класс символов

Если вы хотите сопоставить все знаки препинания, вы можете использовать класс символов [:punct:].

grepl("[[:punct:]]", c("//", "[", "(", "{", "?", "^", "$"))
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE

stringi сопоставляет это с общей категорией Unicode для знаков препинания, поэтому его поведение немного отличается.

stri_detect_regex(c("//", "[", "(", "{", "?", "^", "$"), "[[:punct:]]")
## [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

Вы также можете использовать кросс-платформенный синтаксис для доступа к UGC.

stri_detect_regex(c("//", "[", "(", "{", "?", "^", "$"), "\\p{P}")
## [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

Используйте \ Q \ E escape-последовательности

Размещение символов между \\Q и \\E заставляет обработчик регулярных выражений обрабатывать их буквально, а не как регулярные выражения.

grepl("\\Q.\\E", "a.b")
## [1] TRUE

rebus позволяет писать буквальные блоки регулярных выражений.

literal(".")
## <regex> \Q.\E

Не используйте регулярные выражения

Регулярные выражения - не всегда ответ. Если вы хотите сопоставить фиксированную строку, вы можете сделать, например:

grepl("[", "a[b", fixed = TRUE)
stringr::str_detect("a[b", fixed("["))
stringi::stri_detect_fixed("a[b", "[")
person Community    schedule 31.12.2014
comment
Использование cat для просмотра эффекта экранирования с помощью обратной косой черты подсвечивается. - person Sam Firke; 06.11.2015
comment
Спасибо за советы \\Q и \\E. Никогда не замечал, что он был похоронен в ?base::regex. - person dnlbrky; 05.12.2016
comment
работает как шарм stringr::str_detect("a[b", fixed("[")) - person Pablo Casas; 01.08.2018

Я думаю, что самый простой способ сопоставить символы вроде

\^$.?*|+()[

используют классы символов из R. Чтобы очистить заголовки столбцов из файла данных, который может содержать пробелы и знаки препинания, выполните следующие действия:

> library(stringr)
> colnames(order_table) <- str_replace_all(colnames(order_table),"[:punct:]|[:space:]","")

Этот подход позволяет нам строить классы символов для соответствия символам пунктуации в дополнение к пробельным символам, что вам обычно приходится экранировать с помощью \\, чтобы обнаружить. Вы можете узнать больше о классах персонажей в этой шпаргалке ниже, а также можете ввести ?regexp, чтобы узнать больше об этом.

https://www.rstudio.com/wp-content/uploads/2016/09/RegExCheatsheet.pdf

person petergensler    schedule 21.10.2016