Thomas Z. schrieb:> Bei $TableNew wurden statt /, ! zum trennen der Felder genutzt.> Also:> $TableNew =~ s!REGEXzuersetzen!ErsetzenMIt!Optionen;
Danke, ich hatte schon die Vermutung, konnte in meinen Büchern aber
keine Aussage finden, dass das ! als Trennzeichen verwendet werden darf.
Und hatte auf eine andere Funktion spekuliert.
RegExes sind eigentlich komplizierter als normales "Search & Replace",
So gilt z.B. \s für einen Space Character (Leertaste, TAB, Was auch
immer...) und es gibt auch Quantoren (z.B. meint \s*: Keinen oder
Beliebig Viele Leerzeichen an dieser Stelle).
Damit solltest du eigentlich alles entschlüsseln können.
Bleibt noch zu erwähnen dass man HTML eigentlich NICHT mit RegExes
parsen kann/sollte. Das klappt zwar bei Vorgegebener Struktur, aber wenn
du das Thema auf Englisch googlest siehst du, dass die Leute sich da
nahezu bekriegen :P
Daher: Vielleicht tust du dich je nach Anwendungsfall mit einem XML/HTML
Parser leichter.
Als Feldtrenner muss man -- wie schon erwähnt wurde -- nicht zwingend
den üblichen / nehmen.
Das ist z.B. sinnvoll, wenn die Ausdrücke selbst viele / enthalten. Bei
diesen müsste man sonst jeden einzelnen / mit \ escapen und ewig Fehler
suchen, weil man einen vergessen hat.
http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators
"Any non-whitespace delimiter may replace the slashes."
perlzulangsamNEoda schrieb:> Danke, ich hatte schon die Vermutung, konnte in meinen Büchern aber> keine Aussage finden, dass das ! als Trennzeichen verwendet werden darf.
Insofern ich weiß kann man fast beliebige Zeichen als Trennzeichen
verwenden:
s/dies/mitjenem/g
s'dies'mitjenem'g
sZdiesZmitjenemZg
ist alles erlaubt und das gleiche. Ist vor allem hilfreich wenn "dies"
oder "mitjenem" /-Zeichen enthält.
EDIT: Ah, Tom war schneller.
Tom schrieb:> Als Feldtrenner muss man -- wie schon erwähnt wurde -- nicht> zwingend> den üblichen / nehmen.>> Das ist z.B. sinnvoll, wenn die Ausdrücke selbst viele / enthalten. Bei> diesen müsste man sonst jeden einzelnen / mit \ escapen und ewig Fehler> suchen, weil man einen vergessen hat.>> http://perldoc.perl.org/perlop.html#Regexp-Quote-L...> "Any non-whitespace delimiter may replace the slashes."
Danke für den Tipp, dann kann ich mir soweit helfen.
>Das klappt zwar bei Vorgegebener Struktur, aber wenn
du das Thema auf Englisch googlest siehst du, dass die Leute sich da
nahezu bekriegen :P
Stimmt, aber ich konnte auf die schnelle keinen vernüpftigen Grund
finden, warum das so nicht gemacht werden soll. Kannst du mir einen
nennen?
Die korrekte Antwort wäre: Es geht um die Chomsky Hierarchie.
So gibt es z.B.
http://ddi.cs.uni-potsdam.de/Forschung/SIMBA/export/mod-lklass/bilder/chomsky-h.png
hier eine Auflistung.
Ein Vernünftiges Beispiel kann ich nur indirekt Liefern:
Stelle dir vor, du möchtest den Text eines Paragraph (<p>) parsen, dann
ist es aber erlaubt ihn beliebig zu nesten:
1
/<p>(.*)</p>/
funktioniert ja zunächst, aber was machst du bei:
1
<p>
2
<p>Text</p>
3
</p>
Das wiederum ist auch kein Problem:
1
/<p>\s*<p>(.*)</p>\s*</p>/
ABER: Du könntest mit z.B.
1
/(<p>(.*)</p>)+
zwar theoretisch unendliche Paragraphen auffangen, aber eben nur, wenn
diese konsekutiv (nacheinander) vorkommen, aber eben nicht nested
(Verzeigt).
Stelle dir vor, du hättest 5 Ebenen. Das wäre natürlich noch machbar,
einfach copy und paste, aber was machst du bei UNENDLICH möglichen
Ebenen?
Dafür nutzt man dann eher Bäume, sprich man geht immer eine Ebene tiefer
und mit den Closing Tags dann wieder hoch.
Der Grund ist der, dass man eben nicht S -> <p>S</p> sondern NUR S ->
<p>S oder S-> s</p> definieren kann, sprich nur Sprachen, wie man sie
bei der Handschrift hätte (Ein Zeichen nach dem anderen, aber nicht
wieder vorne was einfügen).
ALLERDINGS: Wenn die Struktur bekannt ist (z.B. die maximale Tiefe
vorgegeben ist), dann kannst du sehr wohl ein RegEx dafür bauen, es wird
aber irgendwann eklig und aufwendig und das bei reduzierter Freiheit
(der Struktur)
Perl0Matiko schrieb:> my $Position = () = $2 =~ m{(</th>)}g;
Auf der rechten Seite hast du den "match"-Operator "m". Das Argument
(wonach gesucht wird) ist diesmal nicht in // oder || oder !!
gefasst, sondern in {}. Gematcht wird $2, also die zweite Fundstelle
der vorangegangenen Suche.
Das Ergebnis des match-Operators ist (außer, dass er $1 neu setzt,
und zwar mit dem gefundenen String "</th>") ein Wahrheitswert, der
darüber aussagt, ob etwas gefunden worden ist.
Das mit () kannte ich auch noch nicht ;), scheint ein numerisches
Ergebnis zu erzwingen, also 0 oder 1. Wenn man das weglässt, bekommt
man bei "no match" statt der 0 einen leeren Wert.
Ansonsten waren reguläre Ausdrücke schon immer "write-only".
Tom schrieb:> Das ist z.B. sinnvoll, wenn die Ausdrücke selbst viele / enthalten. Bei> diesen müsste man sonst jeden einzelnen / mit \ escapen und ewig Fehler> suchen, weil man einen vergessen hat.
Auch als "leaning toothpick syndrome" bekannt:
https://en.wikipedia.org/wiki/Leaning_toothpick_syndrome
Ich kann meinen Beitrag nicht mehr Editieren, daher:
Hier ist noch eine wie ich finde schöne, weitergehende Erklärung dazu
http://stackoverflow.com/a/6752487
Jörg W. schrieb:> Perl0Matiko schrieb:>> my $Position = () = $2 =~ m{(</th>)}g;
[...]
> Das mit () kannte ich auch noch nicht ;), scheint ein numerisches> Ergebnis zu erzwingen, also 0 oder 1. Wenn man das weglässt, bekommt> man bei "no match" statt der 0 einen leeren Wert.
Damit bringst du die Match-Expression in List-Context, das Ergebnis ist
also eine Liste mit n Treffern, die Zuweisung bringt das in
Scalar-Context, wodurch dann die Zahl der Elemente gespeichert wird.
Eine Alternative wäre "0+(EXPRESSION)", wodurch das Ergebnis der
Expression auch in eine Zahl umgewandelt würde und 0+'' ergibt eben 0.
Ist evtl. besser verständlich, aber auch nicht perfekt.