web-dev-qa-db-fra.com

Comment gérer des caractères spéciaux tels que \ ^ $.? * | + () [{Dans ma regex?

Je souhaite faire correspondre un caractère spécial d'expression régulière , \^$.?*|+()[{. J'ai essayé:

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

(Équivalemment, stringr::str_detect(x, "[") ou stringi::stri_detect_regex(x, "[").)

Doubler la valeur pour y échapper ne fonctionne pas:

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

L'utilisation d'une barre oblique inversée ne le fait pas non plus:

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

Comment faire correspondre des caractères spéciaux?


Quelques cas particuliers de cela dans des questions assez anciennes et bien écrites pour qu'il soit aussi effronté que des doublons:
Périodes échappées dans les expressions régulières R
Comment échapper à un point d'interrogation dans R?
tuyau sortant ("|") dans une regex

60
Richie Cotton

S'échapper avec une double barre oblique inverse

R traite les barres obliques inverses comme des valeurs d'échappement pour constantes de caractère . (... et les expressions régulières également. C'est pourquoi nous avons besoin de deux barres obliques inverses lorsque vous fournissez un argument de caractère pour un motif. Le premier n'est pas réellement un caractère, mais il en fait plutôt un autre.) Vous pouvez voir comment ils sont traités avec 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: €

Lectures supplémentaires: L'évitement d'une barre oblique inversée avec une barre oblique inversée dans R génère deux barres obliques inverses dans une chaîne, pas 1

Pour utiliser des caractères spéciaux dans une expression régulière, la méthode la plus simple consiste généralement à les échapper avec une barre oblique inversée, mais comme indiqué ci-dessus, la barre oblique inversée elle-même doit être échappée.

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

Pour faire correspondre les barres obliques inverses, vous devez double d'échappement, ce qui donne quatre barres obliques inverses.

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

Le paquetage rebus contient des constantes pour chacun des caractères spéciaux afin de vous éviter de taper des barres obliques.

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

Pour plus d'exemples, voir:

?SpecialCharacters

Votre problème peut être résolu de cette façon:

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

Former une classe de personnage

Vous pouvez également mettre les caractères spéciaux entre crochets pour former une classe de caractères .

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

Deux des caractères spéciaux ont une signification spéciale à l'intérieur des classes de caractères: \ et ^.

La barre oblique inverse doit toujours être échappée, même si elle se trouve dans une classe de caractères.

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

Caret n'a besoin d'être échappé que s'il se trouve juste après le crochet d'ouverture.

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

rebus vous permet également de former une classe de caractères.

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

Utiliser une classe de caractères préexistante

Si vous souhaitez faire correspondre toutes les ponctuations, vous pouvez utiliser la classe de caractères [:punct:].

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

stringi associe cela à la catégorie générale Unicode pour la ponctuation, son comportement est donc légèrement différent.

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

Vous pouvez également utiliser la syntaxe multiplate-forme pour accéder à un UGC.

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

Utiliser\Q\E échappe

En plaçant des caractères entre \\Q et \\E, le moteur des expressions régulières les traite au pied de la lettre plutôt que comme des expressions régulières.

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

rebus vous permet d'écrire des blocs littéraux d'expressions régulières.

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

N'utilisez pas d'expressions régulières

Les expressions régulières ne sont pas toujours la réponse. Si vous voulez faire correspondre une chaîne fixe, vous pouvez le faire, par exemple:

grepl("[", "a[b", fixed = TRUE)
stringr::str_detect("a[b", fixed("["))
stringi::stri_detect_fixed("a[b", "[")
86
Richie Cotton

Je pense que la meilleure façon de faire correspondre les personnages comme

\^$.?*|+()[

utilisez des classes de caractères à partir de R. Considérez ce qui suit pour nettoyer les en-têtes de colonnes d'un fichier de données pouvant contenir des espaces et des caractères de ponctuation:

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

Cette approche nous permet de chaîner des classes de caractères pour les faire correspondre aux caractères de ponctuation, en plus des caractères d'espacement, ce que vous devriez normalement échapper avec \\ à détecter. Vous pouvez en apprendre plus sur les classes de personnages sur cette feuille de triche ci-dessous, et vous pouvez également taper ?regexp pour obtenir plus d'informations à ce sujet.

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

1
petergensler