Unerwartetes Verhalten von \number bei re.sub()

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
skirnir
User
Beiträge: 33
Registriert: Sonntag 25. Januar 2015, 10:59

Hallo zusammen!

Ich bin gerade dabei, einige Perl-Skripte nach Python zu migrieren. Dazu will ich den Quellcode für einen Hash automatisch in Code für ein dictionary umwandeln.
Quelldatei:

Code: Alles auswählen

$bla{'123'}=456;
$bla{'789'}=23;
Mein bisheriger Code:

Code: Alles auswählen

import re

with open("hash.pl", "r") as infile:
    instring = infile.read()
    outstring = re.sub(u"\$bla\{'([0-9]+)'\}=([0-9]+);", u"bla['\1'] = \2", instring)
#    outstring = re.sub("\$bla\{'(\d+)'\}=(\d+);", "bla['\1'] = \2", instring)
#    outstring = re.sub("\$bla\{'([^}]+)'\}=([^)]+);", "bla['\1'] = \2", instring)
    print outstring
(die beiden auskommentierten Zeilen liefern dasselbe Ergebnis. Statt u"" habe ich auch "" probiert).

Der Output:

Code: Alles auswählen

$ python hash2dict.py 
bla[''] = 
bla[''] = 
(Da man nicht wirklich was sieht, habe ich hier einen Screenshot hochgeladen).

Andererseits produziert das entsprechende Perl-Skript:

Code: Alles auswählen

use strict;
use warnings;
use File::Slurp;

my $infile = read_file('hash.pl');

$infile =~ s/\$bla\{'(\d+)'\}=(\d+);/bla['\1'] = \2/g;
print $infile;
Den erwarteten Ouput:

Code: Alles auswählen

$ perl hash2dict.pl 
\1 better written as $1 at hash2dict.pl line 7.
\2 better written as $2 at hash2dict.pl line 7.
bla['123'] = 456
bla['789'] = 23
Ok, die warnings sind unschön, aber ich wollte den Code zu Demozwecken möglichst ähnlich zum Python-Code haben.

Auf den ersten Blick sieht es nach einem encoding-Problem aus. Allerdings finde ich es unwahrscheinlich, dass einfache Ziffern zu nicht darstellbaren Zeichen werden, indem man sie mit einer Regex matcht. Was macht python da anders als perl?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@skirnir: \ leitet in Python eine Escape-Sequenz ein, und \123 ist die Escape Sequenz für das Zeichen mit der Oktalzahl 123. Du mußt also den Ersetzungsstring mit r"..." als raw markieren.
skirnir
User
Beiträge: 33
Registriert: Sonntag 25. Januar 2015, 10:59

Ja, das war es. Vielen Dank für die Erklärung!
Antworten