Frage

Ich habe eine Perl-Anwendung, die von der Kommandozeile nimmt eine Eingabe wie:

application --fields 1-6,8

Ich bin verpflichtet, um die Felder anzuzeigen, wie vom Benutzer auf der Kommandozeile angefordert werden.

Ich dachte, substituiert '-'. Mit '..', so dass ich sie in Array beispiel speichern

$str = "1..15,16" ;
@arr2 = ( $str ) ;
@arr = ( 1..15,16 ) ;
print "@arr\n" ;
print "@arr2\n" ;

Das Problem hier ist, dass @arr gut funktioniert (wie es sein soll), aber in @ arr2 die gesamte Zeichenfolge nicht als Array-Elemente erweitert wird.

Ich habe versucht, Escape-Sequenzen verwenden, aber kein Glück.

Kann es auf diese Weise getan werden?

War es hilfreich?

Lösung

Wenn dieser Benutzer eingegeben wird, nicht Zeichenfolge eval auf sie aus, wenn Sie irgendwelche Sicherheitsbedenken haben überhaupt.

Versuchen Sie Zahl mit :: Bereich statt:

 use Number::Range;

 $str = "1..15,16" ;
 @arr2 = Number::Range->new( $str )->range;
 print for @arr2;

Um zu vermeiden, auf einem ungültigen Bereich zu sterben, tun:

 eval { @arr2 = Number::Range->new( $str )->range; 1 } or your_error_handling

Es ist auch Set :: IntSpan , die verwendet - statt ..:

 use Set::IntSpan;

 $str = "1-15,16";
 @arr2 = Set::IntSpan->new( $str )->elements;

, aber es erfordert, dass die Bereiche, um zu sein und nicht überlappend (es für den Einsatz auf .newsrc Dateien geschrieben wurde, wenn jemand erinnert sich, was diese sind). Es ermöglicht auch unendlich Bereiche (wo der String beginnt - Zahl oder Enden Zahl -)., Die die Elemente Methode quaken auf

Andere Tipps

Sie denken an @arr2 = eval($str); Da Sie Eingabe nehmen und dass die Bewertung, müssen Sie vorsichtig sein. Sie sollten wahrscheinlich @arr2 = eval($str) if ($str =~ m/^[0-9.,]+$/)

P. S. Ich wusste nicht, über die Anzahl :: Bereich Paket, aber es ist super . Nummer :: Bereich ftw.

Ich hatte das gleiche Problem mit der Ausgabe des Bit im Umgang :: Vector :: to_Enum. Ich löste es, indem Sie:

$range_string =~ s/\b(\d+)-(\d+)\b/expand_range($1,$2)/eg;

dann auch in meiner Datei:

sub expand_range
{
    return join(",",($_[0] .. $_[1]));
}

So "1,3,5-7,9,12-15" verwandelt sich in "1,3,5,6,7,9,12,13,14,15".

Ich hat versucht, wirklich schwer, diese Expansion im zweiten Teil der s zu setzen /// so würde ich nicht, dass zusätzliche Funktion benötigen, aber ich konnte es nicht zur Arbeit kommen. Ich mag das, weil während Anzahl :: Bereich funktionieren würde, auf diese Weise habe ich nicht in einem anderen Modul für etwas ziehen, die trivial sein sollte.

@arr2 = ( eval $str ) ;

Works, obwohl natürlich Sie haben mit eval sehr vorsichtig sein ().

Sie könnten eval verwenden:

$str = "1..15,16" ;
@arr2 = ( eval $str ) ;
@arr = ( 1..15,16 ) ;
print "@arr\n" ;
print "@arr2\n" ;

Obwohl, wenn dieser Benutzer eingegeben wird, werden Sie wahrscheinlich zunächst einige Validierung auf der Eingabezeichenfolge tun wollen, um sicherzustellen, dass sie nicht eingegeben etwas vertrackt.

Verwenden Sie split:

@parts = split(/\,/, $fields);

print $parts[0];
1-6
print $parts[1];
8

Sie können nicht nur einen String setzen enthalten ‚‘ in einem Array, und erwarten, dass es Elemente drehen (außer, wenn Sie einige Perl schwarze Magie verwenden, aber wir werden nicht in diese hier gehen)

Aber Regex und Split sind deine Freunde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top