2012-09-26 5 views
5

Ich schreibe ein Python-Skript, das Dateipfade als Zeichenfolgen akzeptiert, analysiert sie, hängt einen Befehlsnamen an und erstellt eine Liste, die zur Ausführung an subprocess.Popen() übergeben wird. Dieses Skript behandelt sowohl Unix- als auch Windows-Dateipfade und sollte letztendlich auf beiden Systemen ausgeführt werden.Wie verhindert man das automatische Entkommen von Sonderzeichen in Python

Wenn ich dies unter Unix ausführen, wenn ich einen Windows-Pfad geben, der versehentlich ein Escape-Zeichen enthält (z. B. \Users\Administrator\bin), interpretiert Python die eingebettete \b als Backspace-Zeichen. Ich möchte das verhindern.

Soweit ich weiß, gibt es keine Funktion oder Methode, um eine String-Variable als eine rohe Zeichenfolge zu bezeichnen. Der Modifikator 'r' funktioniert nur für Zeichenfolgenkonstanten.

Bisher ist die nächste, die ich habe in der Lage gewesen, dies zu erhalten:

winpath = "C:\Users\Administrator\bin" 
winpath = winpath.replace('\b','\\b') 
winpathlist = winpath.split('\\') 

An dieser Stelle sollte winpathlist ['C:','Users','Administrator','bin'] enthält, nicht ['C','Users','Administrator\x08in'].

kann ich keine weiteren Anrufe winpath.replace() fügen Sie die anderen Fluchten zu behandeln ich bekommen könnte - \a, \f, \n, \r, \t, \v - aber nicht \x.

Gibt es einen mehr pythischen Weg, dies zu tun?

+5

Wie erhalten Sie den Wert in die Zeichenfolge? Python sollte das \ b nicht als Escape behandeln, es sei denn, es befindet sich in einem Zeichenfolgenliteral, oder es wird zunächst als Escape in die Zeichenfolge eingefügt. (Auch Schrägstriche funktionieren gut.) – geoffspear

+0

@Wooble: Im Moment kommt es über Doctest. >>> myCommandObject.setExcecutablePath ('C: \ Programme \ cygwin \ cdrive \ bin') Dabei enthält myCommandObject einen Befehlsnamen (z. B. 'ps'), einen Pfad und eine Liste mit Argumenten. Das Ändern der Schrägstriche von umgekehrten Schrägstrichen in Schrägstriche ist keine Option; Mein Kunde hat ausdrücklich erklärt, dass dies das ist, was er wollte. – poltr1

+0

Wie gesagt, r funktioniert nur für String-Literale; Es funktioniert nicht für String-Variablen. Ich betrachte das führende r als Kluge. Wie auch immer, hier ist der doctest (oder einen Teil davon): >>> myCommand.setExecutablePath ('C: \ Programme \ cygwin \ cdrive \ bin') >>> myCommandList = myCommand.getLaunchList() >> > myCommandList ['C: \\\\ Programme \\\\ cygwin \\\\ cdrive \\\\\\\\\\\\\\ ps', '-e', '-f'] >>> myCommandList [0] .split ("\\\\") ['C:', 'Programme', 'cygwin', 'cdrive', 'bin', 'ps'] Ich bekomme keine mehr Fehler, jetzt, da ich den Aufruf zum Ersetzen hinzugefügt habe. – poltr1

Antwort

6

Wenn Ihr winpath fest codiert ist, können Sie r vor der Zeichenfolge verwenden, um anzugeben, dass es sich um eine "raw string" handelt.

winpath = r"C:\Users\Administrator\bin" 

Wenn winpath nicht fest einprogrammiert werden, können Sie versuchen, eine neue Zeichenfolge zu erstellen:

escaped_winpath = "%r" % winpath 

(die nur repr(winpath) ist, und wird nicht wirklich helfen, wie repr("\bin") ist ...)

eine Lösung wäre die Zeichenfolge von Grund auf neu zu erstellen: Sie ein Beispiel für Funktion bei that link finden kann, aber die allgemeine Idee ist:

escape_dict={'\a':r'\a', 
      '\b':r'\b', 
      '\c':r'\c', 
      '\f':r'\f', 
      '\n':r'\n', 
      '\r':r'\r', 
      '\t':r'\t', 
      '\v':r'\v', 
      '\'':r'\'', 
      '\"':r'\"'} 

def raw(text): 
    """Returns a raw string representation of text""" 
    new_string='' 
    for char in text: 
     try: 
      new_string += escape_dict[char] 
     except KeyError: 
      new_string += char 
    return new_string 

und jetzt, raw("\bin") gibt Ihnen "\\bin" (und nicht "\\x08in") ...

+0

Ich bin nicht vertraut mit Rep(). Ist es in 2.6? Ich mag diese Idee und werde daran festhalten, falls ich sie in Zukunft brauche. Auf Wunsch meines Kunden habe ich die Anrufe ersetzt(). Stattdessen schlug er vor, den Windows-Pfad-Test aus dem Doctest in eine separate Datei zu verschieben. Danke für den Vorschlag. – poltr1

4

Sie können durch das Voranstellen r zum Stringliteral Notation

r"hello\nworld" 

wird

"hello\\nworld" 
eine rohe Zeichenfolge erstellen

Sie können weitere Informationen lesen here

+0

Negativ. Wenn ich das r in die Doctest-Zeichenfolge einfüge, wie Sie es vorschlagen, wird es Teil der Zeichenfolge. – poltr1