(Hallo|Hi(ho)|Tag) Oliver,
ich tüftelt gerade an einem Problem.
Ich habe einen String, dessen Inhalt ich bei Auftreten eines Semikolons trennen möchte. Allerdings können in dem String auch Entitities in der Form > bei denen ich natürlich nicht nach dem Semikolon trennen möchte.Momentaner Ansatz:
my @terms = split(/(?<!>);/,$string);
Das funktioniert sehr gut, solange die Entität genau definiert ist. Allerdings kann man das nicht verallgemeinern zu &#.+ da Lookahead nur bei fester Länge funktioniert. Da kommt sonst die Meldung variable length not implemented.
Das Lookbehind-Assertions nicht mit variablen Längen funktionieren, ist ja nun geklärt ...
Hat vielleicht jemand einen Lösungsansatz - eventuell auch ganz andere Herangehensweise?
Schreib dir eine eigene Funktion, die $string nach Semikola und Entitäten abklappert, aber nur bei allein stehenden Semikola abschnippelt ...
Wenn es denn aber unbedingt mit split() funktionieren muss, versuch mal das hier:
my $string = 'Test; Bla ϑ Blubb; Fred & Barney; Meyer & Co.; nicht … und so weiter';
my @terms;
@terms = split /(?<!&.{2})(?<!&.{3})(?<!&.{4})(?<!&.{5})(?<!&.{6})(?<!&.{7})(?<!&.{8});/, $string;
Sieht zwar nicht sehr elegant aus, dürfte aber seinen Zweck erfüllen. Schließlich kann man mehrere Assertions ohne weiteres nebeneinander setzen -- sie werden quasi UND-verknüpft.
Dieses Konstrukt deckt Entitäten ab, die in folgenden Bereichen liegen:
# kürzeste
# <
# 
# längstmögliche
# ϑ # eine längere CCE kennt mein Opera nicht ;-)
# �
# �
Zusätzlich zu beachten wäre, dass ...
... keine freifliegenden "&"s im Text vorkommen dürfen, sonst passiert sowas wie oben bei "Meyer & Co;" angegeben.
... die RegEx-Engine dann natürlich bei jedem gefundenen Semikolon bis zu 7 Assertions prüfen muss.
Wenn du im Ausgangstext nur numerische Character References hast, kannst du die Suchmuster auch entsprechend anpassen:
/(?<!&#.{2})(?<!&#.{3})(?<!&#.{4})(?<!&#.{5})(?<!&#.{6})(?<!&#.{7});/
MffG
EisFuX