2012-03-30 3 views
9

Ultimamente ho lavorato molto con perl, ancora non so come <,>,>=,=<, ne,gt, ecc. Su "numeri" stringati, per "numero" intendo qualcosa come: '1.4 .5.6.7.8.0'Perl confronta operatori e stringhe "numeri"

mi corregga se sbaglio, i seguenti rendimenti vero:

if ('1.4.5' > '8.7.8'); 

perché entrambi saranno costretti a true (non una stringa vuota). ma, come funziona ne,gt, ecc. Gli operatori di stringhe lavorano su tali numeri?

fondamentalmente sto cercando di confrontare i numeri di versione è la seguente forma:

1.3.4.0.2 

posso fare un confronto numerico di ogni cifra, ma prima, mi ranther vogliono sapere delle operatori di stringa a confronto eseguire su tali stringhe.

Grazie,

+1

"1.4.5.6.7.8.0" non è un numero. Vedi [perldata] (http://perldoc.perl.org/perldata.html) e [Scalar :: Util] (http://search.cpan.org/perldoc?Scalar::Util) è 'looks_like_number'. – ikegami

+0

Ho detto "numeri" – snoofkin

+1

In realtà, hai detto "numero": "per" numero "intendo qualcosa come: '1.4.5.6.7.8.0'». E poi hai usato «'> '», che richiede un * numero * su ciascun lato, quindi il mio commento è appropriato anche se hai detto "numeri". – ikegami

risposta

17

Primo: Si prega di use warnings tutto il tempo. Si sarebbe reso conto quanto segue in una sola volta:

$ perl -wle 'print 1 unless "1.4.5" > "8.7.8"' 
Argument "8.7.8" isn't numeric in numeric gt (>) at -e line 1. 
Argument "1.4.5" isn't numeric in numeric gt (>) at -e line 1. 

Perl v5.9.0 venne distribuito con version. E questo modulo lo rende molto facile per confrontare i numeri di versione:

use warnings; 
use version; 

my ($small, $large) = (version->parse('1.4.5'), version->parse('8.7.8')); 

print "larger\n" if $small > $large; 
print "smaller\n" if $small < $large; 
8

un confronto di stringhe funziona solo se tutti i numeri tra i punti ha la stessa lunghezza. Un confronto di stringhe non ha alcuna conoscenza di numero e inizierà a confrontare punti e cifre (dato che sono entrambi caratteri in una stringa).

un modulo CPAN che fa esattamente quello che stai cercando There: Sort::Versions

3

Quando si confrontano le stringhe utilizzando gli operatori numerici relazione <, >, ecc, Perl emette un avviso se si use warnings. Tuttavia, Perl tenterà comunque di convertire le stringhe in numeri. Se la stringa inizia con le cifre, Perl userà queste, altrimenti la stringa equivale a 0. Nel tuo esempio comparare '1.4.5' e '8.7.8' ha lo stesso effetto del confronto tra i numeri 1.4 e 8.7.

Ma per ne, gt, ecc. Non importa se le stringhe sono costituite da numeri o altro (compresi i punti). Quindi:

print "greater" if '2.3.4' gt '10.1.2' # prints 'greater' because '2' > '1' stringwise 
print "greater" if '02.3.4' gt '10.1.2' # prints nothing because '0' < '1' stringwise 

Pertanto non è possibile utilizzare né >, <, ecc nè gt, lt, ecc per il confronto versione, si deve scegliere approccio diverso, come proposto in un altro risposte, per esempio.

2

Come @tent sottolineato, @ soluzione SebastianStumpf è vicino, ma non del tutto giusto perché:

>perl -Mversion -e 'my @n = ("1.10", "1.9"); print "$n[0] is " . (version->parse($n[0]) > version->parse($n[1]) ? "larger" : "smaller") . " than $n[1]\n";' 
1.10 is smaller than 1.9 

Per fortuna questo è facilmente risolvibile seguendo il suggerimento in version's documentation:

Il v principali' 'è ora vivamente consigliato per chiarezza, e sarà lanciare un avviso in una versione futura se omesso.

>perl -Mversion -e 'my @n = ("1.10", "1.9"); print "$n[0] is " . (version->parse("v$n[0]") > version->parse("v$n[1]") ? "larger" : "smaller") . " than $n[1]\n";' 
1.10 is larger than 1.9