dies für Größe ausprobieren:
my @numbers = ($moyLargRectNom, $moyHautRectNom, $moyLargRectNom, $moyHautRectNom, $moyLargRectMat, $moyHautRectMat, $moyLargRectMat, $moyHautRectMat);
my @temp = split//, $ligne;
for(@temp) {
if(/^\W*\d\W*$/) {
my $num = shift @numbers;
s/\d+/$num/;
}
}
$ligne = join " ", @temp;
, das eine Liste macht, @temp
, auf der Grundlage der "Wörter" (ungefähr) in $ligne
. Es erstellt eine andere Liste, @numbers
, die eine Liste der Nummern darstellt, die Sie in der Liste ersetzen möchten, in der Reihenfolge, in der sie die Dinge ersetzen sollen. Dann geht es durch @temp
, eins nach dem anderen, und wenn ein gegebenes Element eine Zahl ist (dh entspricht der Regex /^\W*\d\W*$/
, was bedeutet, dass es keine Wortzeichen (also nicht "champs4") hat und mindestens eine Zahl hat - das wird "25346)" zusätzlich zu "25346"), und ersetzen Sie dann den numerischen Teil durch den ersten Wert von @numbers
. Und jetzt, nachdem ich es getestet habe, kann ich Ihnen versichern, dass das tatsächlich funktioniert!
Ich glaube, eine kürzere Implementierung könnte mit map
erreicht werden, aber das wird gut genug für Sie arbeiten.
Vorteile dieses Ansatzes zu Ihrem Ansatz:
Zuerst diese Lösung ist skalierbar. Um mehr als acht Zahlen mit Ihrer Lösung zu ersetzen, müssten Sie eine neue Regex schreiben. Um mehr als acht Zahlen durch meine Lösung zu ersetzen, fügen Sie einfach weitere Einträge zu @numbers
hinzu. Dieser Code könnte in eine Subroutine eingefügt werden, die eine zu ändernde Zeichenfolge und eine Liste mit zu ändernden Zahlen benötigt, und Sie müssen sich keine Gedanken darüber machen, ob sie die richtige Anzahl von Zahlen übergeben haben oder ob sie das richtige Format haben.
Zweitens ist dies auf den ersten Blick ein bisschen leichter zu verstehen. Regexes, solange das von Ihnen verwendete sehr schwer visuell zu analysieren ist. Selbst wenn es funktioniert, muss vielleicht jemand Ihren Code ändern, um etwas anderes zu tun. Wenn Sie einen riesigen Regex verwenden, wird der Rewriter (vielleicht Sie) einfach den Kopf schütteln, Ihren Code hervorheben und auf Löschen drücken und dann neuen Code schreiben, um es zu tun. Mit diesem können sie leicht sehen, was in Ihrem Code passiert, und wenn sie Änderungen daran vornehmen müssen, können sie.
Drittens, wenn Sie in einer bestimmten Anzahl von Alternativen codieren wollen, machen Sie das auch tun können:
my @numbers = ($moyLargRectNom, $moyHautRectNom, $moyLargRectNom, $moyHautRectNom, $moyLargRectMat, $moyHautRectMat, $moyLargRectMat, $moyHautRectMat);
my @temp = split//, $ligne;
my $max_replacements = 8;
for(@temp) {
if(/^\W*\d\W*$/) {
my $num = shift @numbers;
s/\d+/$num/;
last unless --$max_replacements;
}
}
$ligne = join " ", @temp;
Als Randnotiz (die früher angewandt, gilt aber nach wie vor), wird dies scheitern auf Fließkommazahlen - /^\W*\d\W*$/
wird Fließkommazahlen entsprechen, aber s/\d+/$num/
wird keine Fließkommazahlen ersetzen, nur der ganzzahlige Teil.Wenn Sie feststellen, müssen Sie Gleitkommazahlen, ändern Sie diese Zeile:
s/\d+/$num/;
Um dies:
s/\d+|(?:\d+)?\.\d+/$num/;
Das Gleitkommazahlen übereinstimmen sollte.
Hinweis: Sie haben nur 5 geklammerten Gruppen in Ihrem Muster, aber Sie verwenden Rückreferenzierungen $ 6 9 $. Warum? –
Ich kann dein Problem nicht reproduzieren: Auch bei den zusätzlichen Rückreferenzen funktioniert die Ersetzung für mich. Erhalten Sie Fehler- oder Warnmeldungen? –
Hallo Nathan, ich habe 8 Werte in der Zeichenfolge zu ersetzen. – user105265