Eine einfache Möglichkeit, mit regex ist die negated character class (auch in perlreftut sehen es)
open my $fh, '<', $file or die "Can't open $file: $!";
while (my $line = <$fh>)
{
my @fields = $line =~ /([^:\s]+)/g;
}
Die [^...]
Spiele zu verwenden alle Zeichen andere als die im Inneren aufgelistet (nach ^
welche „negiert“). Die +
quantifier bedeutet, dass ein oder mehrere Male übereinstimmen, so dass das gesamte Muster einer Zeichenfolge aus anderen aufeinander folgenden Zeichen als :
und "Leerraum" entspricht. Eine genaue Beschreibung von \s
finden Sie in der Dokumentation. Wenn Sie tatsächlich nur einen einzelnen Literalbereich überspringen möchten, verwenden Sie [^: ]
. All dies ist erfasst von ()
.
Die Suche wird durch die Zeichenfolge aufgrund der globalen Modifikator/g
gehen, finden Sie alle solche Übereinstimmungen. Da es in der Liste context ist, gibt es die Liste der Übereinstimmungen zurück, die @fields
Array zugeordnet ist.
Elemente können "on the fly" durch Indexierung in die Liste ($line =~ /([^:\s]+)/g)[2]
ausgewählt werden. Wenn wir passen $_
ist dies (/([^:\s]+)/g)[2]
.
Ich schlage eine gute Lektüre durch perlreftut, für den Anfang.
Auf der anderen Seite ist es oft einfacher und klarer split
my @fields = split /[:\s]/, $line;
Dies auch regex, durch die für das Muster der Zeichenfolge zu spalten verwendet zu verwenden. Die Zeichenklasse wird nicht negiert, da sie hier das Trennzeichen selbst angibt, entweder :
oder \s
(jedes Trennzeichen kann eines davon sein, sie müssen nicht alle gleich sein).
Ich würde jetzt gerne die spezifische Frage beantworten, aber die Frage ist mir nicht klar.
Es fragt nach „zu überprüfen, ob das dritte Feld der ersten Zeile ist Apple-“, was zum Beispiel getan werden kann, durch
while (<$fh>)
{
if ((/([^:\s]+)/g)[2] eq 'Apple') {
# ....
}
}
aber es ist nicht klar, was damit zu tun. Vielleicht bekommst du das erste Feld von dem was das dritte ist?
Ich schlage vor, ein Array zu bekommen und dann zu verarbeiten.Man kann eine Regex schreiben, um Felder direkt zu identifizieren und auszuwählen, aber das ist spröder und die Regex selbst hängt dann von der Position (und Anzahl) von Feldern ab.
An diesem Punkt sind wir in einem Ratespiel. Wenn Sie mehr Details benötigen, erklären Sie bitte.
Der angegebene awk
Code würde Lori James Lori
ergeben und ich sehe nicht, wie das passt.
Für die spezifische Frage "wie man die Regex ändert" nehme ich an, die Antwort könnte etwas wie '/^([^:] * [:]) {2} James ($ | [:]) /' – tripleee
sein @tripleee Ja, aber ich sehe nicht, was die spezifische Frage ist (die angebotenen Beispiele sind widersprüchlich). Ich habe einen weiteren Abschnitt hinzugefügt ... aber ich fühle, dass ich zu diesem Zeitpunkt in einem Ratespiel bin. (Btw, das muss '{1}' Ich denke? Oder 'Apple' anstelle von' James'.) – zdim
'{1}' ist sinnlos; Wenn etwas nicht wiederholt wird, geben Sie einfach keine Anzahl von Wiederholungen an (sonst würden wir sagen:/J {1} a {1} m {1} e {1} s {1}/'). Ich überspringe die ersten zwei Felder und das folgende Trennzeichen, deshalb ist es zwei Wiederholungen. Aber ja, suchen Sie wahrscheinlich im dritten Feld nach "Apple" oder zielen Sie stattdessen auf das zweite Feld. – tripleee