2013-02-12 6 views
15

Ich möchte einen Regex-Ausdruck erstellen in einigen Zeichenfolgen zu suchen, und so müssen diese Zeichenfolge maskiert werden, bevor ich sie in die Regex setzen kann, so Wenn die gesuchte Zeichenfolge Regex-Zeichen enthält, funktioniert sie immer noch.Gibt es eine R-Funktion, um eine Zeichenfolge für Regex-Zeichen zu entkommen

Einige Sprachen haben Funktionen, die dies für Sie tun (z. B. python re.escape: https://stackoverflow.com/a/10013356/1900520). Hat R eine solche Funktion?

Zum Beispiel (aus Funktion):

x = "foo[bar]" 
y = escape(x) # y should now be "foo\\[bar\\]" 
+0

können Sie eine Beispielzeichenfolge hinzufügen und wie soll die Ausgabe aussehen? –

+3

Die meisten Funktionen für reguläre Ausdrücke haben einen Parameter namens 'fixed', der, wenn er auf TRUE gesetzt ist, das Muster so angleicht, wie es ist. – Dason

+0

Das ist nicht gut - ich möchte eine Regex erstellen, von Eingaben durch den Benutzer - so muss ich die Eingaben "hygienisieren", aber immer noch regex verwenden. – Corone

Antwort

13

I quotemeta Funktion ist eine R-Version von Perl geschrieben haben:

library(stringr) 
quotemeta <- function(string) { 
    str_replace_all(string, "(\\W)", "\\\\\\1") 
} 

ich das Perl-Geschmack von regexps immer verwenden, so funktioniert dies für mich. Ich weiß nicht, ob es für die "normalen" Regexps in R funktioniert.

Edit: Ich habe die Quelle gefunden, die erklärt, warum das funktioniert. Es ist in den Quoting Metacharacters section of the perlre manpage:

Dieses Mal wurde in einem gemeinsamen Idiom verwendet, zu deaktivieren oder die besondere Bedeutung des regulären Ausdruck Metazeichen in einem String zitieren, die Sie für ein Muster verwenden mögen. Einfach zitiert alle Zeichen nicht „Wort“:

$pattern =~ s/(\W)/\\$1/g; 

Wie Sie sehen können, über den R-Code für eine direkte Übersetzung der gleichen Substitution ist (nach einer Reise durch Backslash Hölle). Die manpage sagt auch (Hervorhebung von mir):

Im Gegensatz zu einigen anderen regulären Ausdruck Sprachen, es gibt keine backslashed Symbole sind, die nicht alphanumerische sind.

was meinen Punkt unterstreicht, dass diese Lösung nur für PCRE garantiert ist.

+0

Sie sollten beachten, dass Sie stringr verwenden – Dason

+0

Hoppla, ja, ich habe das vergessen! –

6

Offenbar gibt es eine Funktion escapeRegex im Hmisc Paket genannt. Die Funktion selbst hat die folgende Definition für einen Eingabewert von ‚string‘:

gsub("([.|()\\^{}+$*?]|\\[|\\])", "\\\\\\1", string) 

meine Antwort:

Ich bin nicht sicher, ob es eine eingebaute Funktion, aber man konnte man machen zu tun was du willst. Dies erzeugt im Grunde genommen nur einen Vektor der Werte, die Sie ersetzen wollen, und einen Vektor dessen, mit dem Sie sie ersetzen wollen, und durchläuft anschließend die notwendigen Ersetzungen.

re.escape <- function(strings){ 
    vals <- c("\\\\", "\\[", "\\]", "\\(", "\\)", 
       "\\{", "\\}", "\\^", "\\$","\\*", 
       "\\+", "\\?", "\\.", "\\|") 
    replace.vals <- paste0("\\\\", vals) 
    for(i in seq_along(vals)){ 
     strings <- gsub(vals[i], replace.vals[i], strings) 
    } 
    strings 
} 

Einige Ausgang

> test.strings <- c("What the $^&(){}.*|?", "foo[bar]") 
> re.escape(test.strings) 
[1] "What the \\$\\^&\\(\\)\\{\\}\\.\\*\\|\\?" 
[2] "foo\\[bar\\]" 
+0

Dies ist keine gute Lösung.Sie müssten jedes einzelne spezielle Regexp-Zeichen in "Vals" einschließen, was schwierig werden könnte. –

+0

@RyanThompson Sicher - aber es ist ein Anfang. Und die Liste der Sonderzeichen ist endlich, also ist es keine große Last. Ich sage nicht, dass dies eine optimale Lösung ist - nur dass es eine Möglichkeit ist. Beachten Sie außerdem, dass Ihre Methode möglicherweise Zeichen ausgibt, die normalerweise nicht als Regex-Zeichen betrachtet werden, sodass sie möglicherweise ebenfalls als "schlecht" eingestuft werden. – Dason

+1

Meine Methode kann einige Zeichen enthalten, die nicht maskiert werden müssen, aber das tut nicht weh, da für PCRE * jedes * nicht-alphanumerische Zeichen als Literal verwendet wird, wenn ein Backslash vorangestellt ist, selbst wenn der Backslash ist nicht benötigt. –

Verwandte Themen