Wie gehe ich mit Sonderzeichen wie \ ^ $ um? * | + () [{In meiner Regex?

75

Ich möchte ein anzupassen regulären Ausdruck Sonderzeichen , \^$.?*|+()[{. Ich habe es versucht:

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

(Äquivalent stringr::str_detect(x, "[")oder stringi::stri_detect_regex(x, "[").)

Das Verdoppeln des Wertes, um zu entkommen, funktioniert nicht:

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

Ein Backslash wird auch nicht verwendet:

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

Wie kann ich Sonderzeichen abgleichen?


Einige Sonderfälle in Fragen, die alt und gut genug geschrieben sind, um frech zu sein und als Duplikate davon geschlossen zu werden:
Escaped Periods In R Reguläre Ausdrücke
Wie kann man einem Fragezeichen in R entkommen?
austretendes Rohr ("|") in einem regulären Ausdruck

Richie Cotton
quelle

Antworten:

107

Entfliehen Sie mit einem doppelten Backslash

R behandelt Backslashes als Escape-Werte für Zeichenkonstanten . (... und reguläre Ausdrücke auch. Daher sind zwei Backslashes erforderlich, wenn ein Zeichenargument für ein Muster angegeben wird. Das erste ist eigentlich kein Zeichen, sondern macht das zweite zu einem Zeichen.) Sie können sehen wie sie verarbeitet werden mit 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: €

Weiterführende Literatur: Wenn Sie einen Backslash mit einem Backslash in R umgehen, werden 2 Backslashes in einer Zeichenfolge erzeugt, nicht 1

Um Sonderzeichen in einem regulären Ausdruck zu verwenden, besteht die einfachste Methode normalerweise darin, sie mit einem Backslash zu maskieren. Wie oben erwähnt, muss der Backslash selbst maskiert werden.

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

Um Backslashes abzugleichen, müssen Sie die Escape-Taste verdoppeln, was zu vier Backslashes führt.

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

Das rebusPaket enthält Konstanten für jedes der Sonderzeichen, damit Sie keine Schrägstriche eingeben müssen.

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

Weitere Beispiele finden Sie unter:

?SpecialCharacters

Ihr Problem kann folgendermaßen gelöst werden:

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

Bilden Sie eine Zeichenklasse

Sie können die Sonderzeichen auch in eckige Klammern setzen, um eine Zeichenklasse zu bilden .

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

Zwei der Sonderzeichen haben innerhalb der Zeichenklassen eine besondere Bedeutung: \und ^.

Backslash muss auch dann maskiert werden, wenn es sich innerhalb einer Zeichenklasse befindet.

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

Caret muss nur entkommen, wenn es sich direkt hinter der öffnenden eckigen Klammer befindet.

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

rebus Sie können auch eine Zeichenklasse bilden.

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

Verwenden Sie eine bereits vorhandene Zeichenklasse

Wenn Sie alle Satzzeichen abgleichen möchten, können Sie die [:punct:]Zeichenklasse verwenden.

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

stringi Ordnet dies zur Interpunktion der allgemeinen Unicode-Kategorie zu, sodass sich sein Verhalten geringfügig unterscheidet.

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

Sie können auch die plattformübergreifende Syntax für den Zugriff auf eine UGC verwenden.

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

Verwenden Sie \ Q \ E Escapezeichen

Wenn Sie Zeichen zwischen \\Qund platzieren, werden sie von \\Eder Engine für reguläre Ausdrücke buchstäblich und nicht als reguläre Ausdrücke behandelt.

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

rebus Mit dieser Option können Sie Literalblöcke mit regulären Ausdrücken schreiben.

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

Verwenden Sie keine regulären Ausdrücke

Reguläre Ausdrücke sind nicht immer die Antwort. Wenn Sie mit einer festen Zeichenfolge übereinstimmen möchten, können Sie beispielsweise Folgendes tun:

grepl("[", "a[b", fixed = TRUE)
stringr::str_detect("a[b", fixed("["))
stringi::stri_detect_fixed("a[b", "[")
Richie Cotton
quelle
2
Die Verwendung cat, um den Effekt des Entweichens mit Backslashes zu sehen, leuchtet auf.
Sam Firke
Danke für den \\Qund \\ETipp. Ich habe nie bemerkt, dass es begraben wurde ?base::regex.
dnlbrky
funktioniert wie ein Zauberstringr::str_detect("a[b", fixed("["))
Pablo Casas
1

Ich denke, der einfachste Weg, um die Charaktere wie zusammenzubringen

\^$.?*|+()[

verwenden Zeichenklassen aus R. Beachten Sie Folgendes, um Spaltenüberschriften aus einer Datendatei zu entfernen, die Leerzeichen und Satzzeichen enthalten kann:

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

Dieser Ansatz ermöglicht es uns, Zeichenklassen so zu kennzeichnen, dass sie mit Interpunktionszeichen übereinstimmen, zusätzlich zu Leerzeichen, mit denen Sie normalerweise entkommen müssten, um sie \\zu erkennen. ?regexpWeitere Informationen zu den Charakterklassen finden Sie in diesem Cheatsheet unten. Sie können auch eingeben, um weitere Informationen dazu zu erhalten.

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

Petergensler
quelle