Comment puis-je traiter avec des caractères spéciaux comme ^$.?*|+(){dans ma regex?

je veux correspondre à un expression régulière caractère spécial , ^$.?*|+()[{ . J'ai essayé:

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

(équivalent stringr::str_detect(x, "[") ou stringi::stri_detect_regex(x, "[") .)

doubler la valeur pour l'échapper ne fonctionne pas:

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

ni l'utilisation d'un antislash:

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

Comment faire correspondre des caractères spéciaux?


Certains des cas particuliers de ceci dans des questions qui sont vieilles et assez bien écrites pour qu'il soit cheeky fermer comme des duplicata de ceci:

périodes évitées dans les Expressions régulières R

comment échapper à un point d'interrogation en R?

tuyau d'échappement ( " | ") dans une regex

46
demandé sur k-dubs 2014-12-31 15:15:38

2 réponses

Échapper avec une double barre oblique inverse

R traite les antislashes comme des valeurs d'échappement pour constantes de caractères . (... tout comme les expressions régulières. D'où la nécessité de deux antislashs lors de la fourniture d'un argument de caractère pour un motif. Le premier n'est pas un personnage, mais il fait du second un personnage.) Vous pouvez voir comment ils sont traités en utilisant 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: €

autre lecture: échapper à un backslash avec un backslash en R produit 2 backslashs dans une chaîne de caractères, pas 1

pour utiliser des caractères spéciaux dans une expression régulière la méthode la plus simple est généralement de Les échapper avec un antislash, mais comme noté ci-dessus, le antislash lui-même doit être échappé.

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

pour correspondre backslashs, vous devez double évasion, résultant en quatre backslashs.

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

le paquet rebus contient des constantes pour chacun des caractères spéciaux pour vous éviter d'utiliser des slashes erronés.

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")

la Forme d'une classe de caractères

vous pouvez également envelopper 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 particulière à l'intérieur des classes de caractères: \ et ^ .

Backslash doit toujours être échappé même s'il est à l'intérieur d'une classe de caractères.

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

Lambda n'a besoin d'être échappé si c'est directement 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 voulez assortir toute la ponctuation, vous pouvez utiliser la classe de caractères [:punct:] .

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

stringi correspond à la catégorie générale Unicode pour la ponctuation, de sorte que son comportement est 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

Use \Q \ e évasions

placer des caractères entre \Q et \E fait que le moteur d'expression régulière les traite littéralement plutôt que comme des expressions régulières.

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

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

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

de Ne pas utiliser des expressions régulières

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

grepl("[", "a[b", fixed = TRUE)
stringr::str_detect("a[b", fixed("["))
stringi::stri_detect_fixed("a[b", "[")
72
répondu Richie Cotton 2018-01-03 11:28:32

je pense que la façon la plus facile de faire correspondre les caractères comme

\^$.?*|+()[

utilisent des classes de caractères de L'intérieur de R. considérez ce qui suit pour nettoyer les en-têtes de colonne d'un fichier de données, qui pourrait 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 string des classes de caractères pour correspondre aux caractères de ponctuation, en plus des caractères blancs, quelque chose que vous auriez normalement à échapper avec \ à détecter. Vous pouvez en savoir plus sur les classes de caractères dans cette fiche de paie ci-dessous, et vous pouvez aussi taper ?regexp pour voir plus d'informations à ce sujet.

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

1
répondu petergensler 2016-10-21 03:29:37