Perl: Wie zum extrahieren einen string zwischen Klammern
Ich habe eine Datei in der moin moin-text-format:
* [[ Virtualbox Guest Additions]] (2011/10/17 15:19)
* [[ Abiword Wordprocessor]] (2010/10/27 20:17)
* [[ Sylpheed E-Mail]] (2010/03/30 21:49)
* [[ Kupfer]] (2010/05/16 20:18)
All den Worten, zwischen den '[[' und ']]' sind die kurz-Beschreibung des Eintrags. Brauch ich zu extrahieren der ganze Eintrag, aber nicht jedes einzelne Wort.
Fand ich eine Antwort für eine ähnliche Frage hier: https://stackoverflow.com/a/2700749/819596
aber nicht verstehen kann, ist die Antwort: "my @array = $str =~ /( \{ (?: [^{}]* | (?0) )* \} )/xg;"
Alles, was funktioniert, wird akzeptiert, aber Erklärungen helfen würde, stark, sprich: was (?0)
oder /xg
tut.
- vielen Dank für die Antworten gonna take ein nap und versuchen, die Antworten!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den code wird wahrscheinlich so Aussehen:
Als ich sehe, was Sie benötigen, kann wie folgt beschrieben werden: in jeder Zeile der Datei versuchen zu finden, diese Folge von Symbolen,...
Als Sie sehen, dass diese Beschreibung ganz natürlich übersetzt in eine regex. Die einzige Sache, die wahrscheinlich nicht notwendig ist
/x
regex-modifier, die mir erlaubt ausgiebig zu Kommentar es. )Wenn der text nie enthalten
]
, können Sie einfach den folgenden wie bereits empfohlen:Folgendes ermöglicht
]
aus dem enthaltenen text, aber ich empfehle, gegen die Einbeziehung in ein größeres Muster:Folgendes ermöglicht
]
in den enthaltenen text, und ist das robusteste Lösung:Beispielsweise
oder
/x
: Ignore whitespace-Zeichen im Muster. Erlaubt Leerzeichen werden Hinzugefügt, um das Muster lesbar, ohne änderung der Bedeutung der Muster. Dokumentiert in perlre./g
: Hier finden Sie alle Spiele. Dokumentiert in perlop.(?0)
wurde verwendet, um die Muster rekursiv, da die verlinkten Knoten zu tun hatte mit beliebiger Verschachtelung von curlies. */g
: Hier finden Sie alle Spiele. Dokumentiert in perlre.\[
ist eine wörtliche [,]
ist ein literal ],.*
bedeutet, dass jeder Folge von 0 oder mehr Zeichen,etwas, was in Klammern eingeschlossen ist eine Aufnahme der Gruppe, damit Sie darauf zugreifen können, später im Skript mit $1 (oder $2 .. $9 je nachdem, wie viele Gruppen Sie haben).
Setzen Sie alle zusammen, Sie wird mit zwei
[
dann alles bis zum letzten vorkommen von zwei aufeinander folgenden]
Update
Auf einem zweiten Lesen deiner Frage habe ich plötzlich verwirrt sind, müssen Sie den Inhalt zwischen [[ und ]], oder die ganze Zeile - in diesem Fall lassen Sie die Klammern vollständig und einfach testen, ob das Muster passt, keine Notwendigkeit zu erfassen.
Die Antwort, die Sie gefunden haben, ist für die recursive-pattern-matching, dass ich glaube, Sie brauchen nicht.
/x erlaubt die Verwendung bedeutungsloser Leerzeichen und Kommentare in der regexp.
/g läuft die regexp, die durch den string. Ohne Sie läuft nur noch bis zum ersten match.
/xg ist /x und /g kombiniert.
(?0) läuft die regexp mal wieder selbst (Rekursion)
Wenn ich verstehe, ok, man braucht so etwas wie dieses:
Ich würde empfehlen, mit "extract_bracketed" oder "extract_delimited" aus dem Modul Text::Balanced - siehe hier: http://perldoc.perl.org/Text/Balanced.html
getestet unter:
dann, da haben wir unsere Daten in \1 wir können einfach verwenden Sie es für den Druck auf der Konsole.
Den " x " - flag bedeutet, dass whitespace wird ignoriert regex, damit ein lesbarer Ausdruck. Die " g " - flag bedeutet, dass das Ergebnis eine Liste aller Spiele von Links nach rechts (match *g*lobally).
Den
(?0)
stellt den regulären Ausdruck innerhalb der ersten Gruppe von Klammern. Es ist eine rekursive reguläre Ausdrücke äquivalent zu einem Satz von Regeln, wie: