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
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")
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> [?]
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
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
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", "[")
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