2009-04-17 18 views
7

Ich brauche String Ersatz in Perl verwenden Übersetzungen zu erleichtern, dh vieleWas soll ich anstelle von printf in Perl verwenden?

print "Outputting " . $n . " numbers"; 

durch so etwas wie

jedoch
printf ("Outputting %d numbers", $n); 

ersetzen, würde Ich mag printf mit einfacher, etwas zu ersetzen, zu analysieren Menschen, wie folgt:

printX ("Outputting {num} numbers", { num => $n }); 

oder allgemein etwas mehr Perly.

Können Sie etwas (von CPAN oder nicht), das Sie mögen und verwenden, empfehlen?

Antwort

12

meisten Templating-Module auf CPAN sein werde wahrscheinlich tun, was du willst. Hier ist ein Beispiel mit Template Toolkit ...

use Template; 
my $tt = Template->new; 

$tt->process(\"Outputting [% num %] numbers\n", { num => 100 }); 


Und Sie können Ihren gewünschten Beispiel mit so etwas wie dieses ...

sub printX { 
    use Template; 
    my $tt = Template->new(START_TAG => '{', END_TAG => '}'); 
    $tt->process(\($_[0] . "\n"), $_[1]); 
} 

und Sie haben nachahmen ...

printX 'Outputting {num} numbers' => { num => 100 }; 
4

Es scheint, dass Sie eine andere Art der String-Analyse haben möchten. Ich würde dir raten, das nicht zu tun. Der einzige, der die Syntax mit dem% d darin sieht, ist der Entwickler und er wird genau verstehen, was gemeint ist. Die printf-Syntax ist wegen der Optionen wie Auffüllen, Dezimalzahlen usw. sehr leistungsfähig.

Ich denke, dass Sie mehr eine Ersetzungsmethode verwenden möchten. Es ist s/{num}/$ n /.

+1

„Der einzige, der ist die Syntax mit dem% d darin zu sehen, ist der Entwickler "-> Das ist nicht der Fall, diese Strings werden von Übersetzern gesehen und ziemlich dumme auch :) Ich würde printf selbst gut machen, aber ich muss an andere denken Leute ... –

1

Angesichts Ihres Kommentars über das Sein für Übersetzer empfehle ich, ein Perl-Skript zu schreiben, das alle printf() streift und sie in einer leichter übersetzerfreundlichen Weise tabelliert.

Etwas wie folgt aus:

while(<>) 
{ 
    #regex for striping printf 

    #print in tabulated form 
} 

Wenn Sie die Zeilennummer zu drucken Sie ein anderes Programm leicht schreiben kann, den übersetzten Text zu ersetzen.

Diese Lösung dauert nicht länger als das erneute Factoring von printf() und es ist wiederverwendbar.


ich auf jeden Fall mit printf() bleiben würde, dann ist es in vielen Sprachen Standard.

Es ist fast ein Standard für String-Ausgabe geworden. Wie i ist für for Schleifen.

+0

Ich benutze "Schleife" :-) –

+3

Das Problem mit printf ist, dass Sie auch die Bestellung richtig bekommen müssen. Das heißt, wenn eine Sprache die Reihenfolge der Elemente, die ersetzt werden sollen, umkehrt, ist der Übersetzer SOL mit einigen Drucken (z. B. C). Um die Übersetzung zu vereinfachen, müssen Sie "% 1 $ d" verwenden, damit sie leicht verschoben werden können. Template Toolkit macht das trivial. – Tanktalus

14

Was ist einfach:

print "Outputting $n numbers"; 

Das ist sehr Perly ist. Wenn Sie keine komplizierte Formatierung benötigen, ist die String-Interpolation der richtige Weg.

+0

Danke für den Vorschlag, das ist in den meisten Fällen die geeignete Idee, denke ich, aber ich gebe nicht immer interpolierbare Variablen aus (Dumper (\% hash) kommt mir in den Sinn). Ich muss sehen, wie das funktioniert, aber ich brauche wahrscheinlich etwas flexibleres ... –

+3

Es gibt ein Idiom, um beliebige Ausdrücke in der Interpolation auszugeben: print "Hash ist: @ {[Dumper (\% hash)]}"; Es ist nicht schön, aber es funktioniert. –

+0

@Greg Hewgill Ich hatte keine Ahnung, dass du das kannst - super! – cowgod

-2

naja, perl hat printf funktion ... warten, willst du sowas wie python's string formatting with dict?

>>> print '%(key)s' % {'key': 'value'} 
value 

mmm, ich weiß es nicht so etwas wie das in Perl existieren ... zumindest nicht dieses "easy" ... vielleicht Text::Sprintf::Named kann dein Freund

+0

Für den Fall, dass es nicht klar war, würde ich etwas anstelle von Perls Printf verwenden, nicht Cs Printf. –

5

Die print builtin ist sehr praktisch für die meisten Situationen. Neben Variableninterpolation:

print "Outputting $n numbers"; # These two lines 
print "Outputting ${n} numbers"; # are equivalent 

Denken Sie daran, dass print mehrere Argumente annehmen kann, so gibt es keine Notwendigkeit, sie verketten zuerst in einen einzigen String, wenn Sie das Ergebnis eines Unterprogramm-Aufruf drucken müssen:

print "Output data: ", Dumper($data); 

Um jedoch andere Zahlen als einfache Ganzzahlen auszugeben, möchten Sie wahrscheinlich die Formatierung von printf vereinfachen. Die Ausgabe anderer Datentypen ist jedoch einfach mit print.

können Sie join verwenden, um bequem das Ausgangsfeld:

print join ', ', @array; 

und verbinden sich mit map und keys zur Ausgabe von Hashes:

print join ', ', map {"$_ : $hash{$_}"} keys %hash; 

Verwenden Sie den qq Operator, wenn Sie um die Daten zur Ausgabe zitiert wollen :

print join ', ', map {qq("$_" : "$hash{$_}"}) keys %hash; 
5

Wenn Sie Übersetzungen vereinfachen möchten, sollten Sie eines der verfügbaren L10n/i18n CPAN-Module in Erwägung ziehen. Genauer gesagt, ein guter Überblick darüber, warum Ihr Ansatz zu Ende geht, ist written up as part of the Local::Maketext docs.

Ein weiteres großartiges Modul, das gut mit Locale :: Maketext zusammenpasst, ist Locale::Maketext::Lexicon. Dadurch können Sie mehr Standard-Lokalisierungsformate wie die .po/.mo-Dateien von gettext verwenden, die über GUI-Tools verfügen, die den Übersetzern dabei helfen, den gesamten zu übersetzenden Text zu bearbeiten. Locale :: Maketext :: Lexicon enthält außerdem ein Hilfsskript (xgettext.pl), mit dem Sie Ihre Lokalisierungsdateien mit Ihren Vorlagen oder Modulen, die Text enthalten, der übersetzt werden muss, auf dem neuesten Stand halten können. Ich hatte in der Vergangenheit sehr gute Ergebnisse mit dieser Art von Setup.

+0

Ich spreche hier nicht über I18n (außer L :: M :: Lexicon ist völlig ungeeignet, dazu später;)), sondern bereite Strings für die Übersetzung vor. Bei meiner Arbeit müssen wir derzeit ein benutzerdefiniertes Übersetzungssystem verwenden, in dem Streicher auf eine seltsame Art extrahiert werden. –

1

Allgemeinen von Draegtun Antwort ist groß, aber wenn man etwas kleiner (dh weniger Speicher) benötigen würde, und nicht so mächtig können Sie leicht tun mit es diese Funktion:

sub printX { 
    my ($format, $vars) = @_; 

    my @sorted_keys = sort { length($b) <=> length($a) } keys %{ $vars }; 
    my $re = join '|', map { "\Q$_\E" } @sorted_keys; 

    $format =~ s/ \{ \s* ($re) \s* \} /$vars->{$1}/xg; 

    print $format; 
} 
Verwandte Themen