2009-04-17 13 views
7

trzeba użyć trochę wymiany strun w Perl ułatwienie tłumaczeń, czyli zastąpić wieleCo powinienem użyć zamiast printf w Perlu?

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

coś jak

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

Jednak chciałbym wymienić printf z czymś łatwiej analizować za ludzie, tak:

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

lub ogólnie coś więcej Perly.

Czy możesz polecić coś (z CPAN czy nie), które lubisz i używasz?

Odpowiedz

12

moduły Większość szablonów na CPAN prawdopodobnie zrobi to, co chcesz. Oto przykład użycia Template Toolkit ...

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

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


I można naśladować swój wymagany przykład z czymś takim ...

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

i masz ...

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

Wygląda na to, że chcesz mieć inny sposób analizowania łańcuchów. Radziłbym ci tego nie robić. Jedynym, który widzi składnię z% d jest deweloperem i dokładnie zrozumie, co to znaczy. Składnia printf jest potężna ze względu na opcje takie jak wypełnienie, miejsca dziesiętne itp.

Myślę, że chcesz użyć więcej metody zastępowania. Jest to perlish zrobić s/{num}/$ n /.

+1

„Tylko ten, kto jest widząc składnię z% d w nim jest programista "-> Tak nie jest, te struny będą widziane przez tłumaczy i całkiem głupie :) Byłbym w porządku z printf sam, ale muszę myśleć o innych ludzie ... –

1

W związku z twoją uwagą na temat bycia dla tłumaczy proponuję napisać skrypt perla, który usunie wszystkie printf() i uporządkuje je w łatwiejszy sposób, bardziej przyjazny dla tłumacza.

coś takiego:

while(<>) 
{ 
    #regex for striping printf 

    #print in tabulated form 
} 

Jeśli wydrukować numer wiersza zbyt łatwo można napisać inny program do wymiany przetłumaczony tekst.

To rozwiązanie nie zajmie więcej czasu niż ponowne faktoring z dala od printf() i można go użyć ponownie.


pewno będę trzymać printf(), to norma w wielu językach.

Stało się prawie standardem dla wyjścia łańcuchowego. Podobnie jak i jest dla pętli for.

+0

Używam "pętli" :-) –

+3

Problem z printf polega na tym, że musisz również uzyskać prawidłowe zamówienie. Oznacza to, że jeśli język odwraca kolejność elementów, które są zastępowane, tłumacz jest SOL z niektórymi printf (powiedzmy C). Aby ułatwić tłumaczenie, musisz użyć "% 1 $ d", aby mogli łatwo go przenosić. Szablon Toolkit sprawia, że ​​jest to banalne. – Tanktalus

14

co po prostu:

print "Outputting $n numbers"; 

To bardzo Perly. Jeśli nie potrzebujesz żadnego fantazyjnego formatowania, interpolacja ciągów jest zdecydowanie drogą do zrobienia.

+0

Dzięki za sugestię, w większości przypadków jest to odpowiedni pomysł, ale nie zawsze wyprowadzam zmienne interpolacyjne (pojawia się na myśl Dumper (\% hash)). Muszę zobaczyć, jak to działa, ale prawdopodobnie potrzebuję czegoś bardziej elastycznego ... –

+3

Istnieje idiom do wyprowadzania dowolnych wyrażeń w interpolacji: print "Hash is: @ {[Dumper (\% hash)]}"; To nie jest ładne, ale działa. –

+0

@Greg Hewgill Nie miałem pojęcia, że ​​możesz to zrobić - super! – cowgod

-2

cóż, perl ma printf funkcję ... czekaj, chcesz coś takiego jak python's string formatting with dict?

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

mmm, nie wiem, coś takiego istnieje w Perlu ... przynajmniej nie to „łatwe” ... może Text::Sprintf::Named może być twoim przyjacielem

+0

Jeśli nie było to jasne, chciałbym użyć czegoś zamiast printf z Perla, a nie printf C. –

5

print wbudowane jest bardzo wygodne w większości sytuacji. Oprócz zmiennej interpolacji:

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

Pamiętaj, że print może trwać wiele argumentów, więc nie ma potrzeby, aby złączyć je najpierw w jeden ciąg, jeśli trzeba wydrukować wynik wywołania podprogramu:

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

Jednakże, dla wyprowadzania liczb innych niż zwykłe liczby całkowite, prawdopodobnie będziesz chciał wygodę formatowania printf. Wydawanie innych typów danych jest jednak łatwe dzięki print.

Można użyć join wygodnie wyjściowych tablic:

print join ', ', @array; 

i połączyć z map i keys do mieszań wyjściowych:

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

użyć operatora qq jeśli chcesz cytatów wyjściowych wokół danych :

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

Jeśli chcesz ułatwić tłumaczenie, powinieneś rozważyć użycie jednego z dostępnych modułów LANn/i18n CPAN. W szczególności dobry przegląd tego, dlaczego Twoje podejście zakończy się niedostatkiem, to written up as part of the Local::Maketext docs.

Kolejny świetny moduł, który ładnie łączy się z Locale :: Maketext, to Locale::Maketext::Lexicon. Pozwala to na użycie bardziej standardowych formatów lokalizacji, takich jak pliki .po/.to gettext, które mają narzędzia GUI, aby pomóc tłumaczom pracować z całym tekstem wymagającym tłumaczenia. Locale :: Maketext :: Lexicon zawiera również skrypt pomocniczy (xgettext.pl), który pomaga zachować aktualne pliki lokalizacyjne w szablonach lub modułach zawierających tekst, który wymaga tłumaczenia. W przeszłości miałem bardzo dobre wyniki z tego typu konfiguracją.

+0

Nie mówię tutaj o I18n (oprócz L :: M :: Lexicon jest całkowicie nieodpowiedni, bardziej do tego później;)), ale raczej przygotowanie ciągów do tłumaczenia. W mojej pracy musimy obecnie używać niestandardowego systemu tłumaczenia, w którym łańcuchy są wydobywane w dziwny sposób. –

1

Generalnie odpowiedź od Draegtun jest super, ale gdyby trzeba coś mniejszego (czyli mniej pamięci), a nie jako potężny można łatwo zrobić to za pomocą tej funkcji:

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; 
} 
Powiązane problemy