Hallo *,
ich mal wieder mit 'nem BUG-Verdacht ...
K o n t e x t
[1] LibreOffice MakroBasic unterstützt (1) die Meta-Zeichen und -Syntax der "ICU Regular Expressions documentation <http://userguide.icu-project.org/strings/regexp>" (2).
[2] "ICU Regular Expressions documentation <http://userguide.icu-project.org/strings/regexp>" unterstützt die "Look-ahead assertion - (?= ... )" und die "Look-behind assertion (?<= ... )".
[3] "&" und "$0" beinhalten das, was via Suchkriterien gefunden wurde (3).
B e z ü g e
(1) LibreOffice WRITER [Datei] > [Suchen und ersetzen...] > [Hilfe] > [Liste der regulären Ausdrücke]: "[...] Für eine vollständige Liste unterstützter Metazeichen und -syntax siehe ICU Regular Expressions documentation <http://userguide.icu-project.org/strings/regexp> (englisch). [...]"
(2) http://userguide.icu-project.org/strings/regexp
(3) LibreOffice WRITER [Datei] > [Suchen und ersetzen...] > [Hilfe] > [Liste der regulären Ausdrücke]: "[...] & oder $0 - Fügt dem Begriff im Feld [Ersetzen] die Zeichenfolge hinzu, die anhand der Suchkriterien im Feld [Suchen] gefunden wurde, wenn Sie eine Ersetzung vornehmen. [...]"
P r o b l e m / F e h l e r
+ Mittels "Look-behind assertion" wird nach der Zeichenkette "DEF" gesucht, der die Zeichenkette "ABC" VORAN-gestellt ist. Mit Hilfe der "Look-behind assertion" wird aber (letztendlich) nicht "ABCDEF" gefunden, sondern (nur) "DEF", was auch so gewollt ist. "DEF" wird dann rot eingefärbt.
+ Mittels "Look-ahead assertion" wird nach der Zeichenkette "UVW" gesucht, der die Zeichenkette "XYZ" NACH-gestellt ist. Mit Hilfe der "Look-ahead assertion" wird aber (letztendlich) nicht "UVWXYZ" gefunden, sondern (nur) "XYZ", was auch so gewollt ist. "XYZ" wird dann blau eingefärbt.
Das funktioniert (im Prinzip) alles, das/der Problem/Fehler kommt erst jetzt:
Mit "&" bzw. "$0" kann man dem oRD.ReplaceString die gefundene Zeichenkette übergeben und das oRD.setReplaceAttributes(aAttR()) erledigt dann die Färbung.
Im Kontext der "Look-behind assertion" beinhalten "&" bzw. "$0" die gefundene Zeichenkette. Im Kontext der "Look-ahead assertion" aber nicht, mit der Folge, dass die gefundene Zeichenkette nicht nur gefärbt, sondern auch durch "&" bzw. "$0" ersetzt wird - und das ist ja wohl nicht ganz richtig.
Man kann zwar den Fehler kompensieren, indem man im Kontext der "Look-ahead assertion" bei oRD.ReplaceString anstatt "&" bzw. "$0" einfach "UVW" angibt, aber es bleibt doch ein Fehler, denn es gibt keinen (syntax- und/oder programmier-logischen) Grund, warum bei der "Look-behind assertion" "&" bzw. "$0" funktionieren und bei der "Look-ahead assertion" "&" bzw. "$0" nicht funktionieren sollten - zumindest sehe ich keinen.
R e p r o d u k t i o n
+ Neues WRITER-Dokument öffnen.
+ Diese 6 Zeilen einfügen:
Look-behind assertion:
ABCDEF
123DEF
Look-ahead assertion:
UVWXYZ
UVW123
+ Makro starten (s.u.)
+ Ergebnis
Bei ABCDEF wird DEF rot gefärbt, sonst nichts.
Bei UVWXYZ wird UVW blau gefärbt, sonst nichts.
==>> Kann jemand den "&/$0"-Fehler bei der "Look-ahead assertion" nachvollziehen UND bestätigen ? <<==
Und bevor mich jemand fragt, ob ich nichts besseres zu tun habe als mich mit solchem "kryptischen Sch..." zu beschäftigen ... Im bin gerade mit Test/Feinschliff bezüglich meines "CodeColorizerBasic"-Makros beschäftigt und dabei beim Testen auf nachfolgenden BasicMakroCode gestoßen:
[1] Variablen-Typ-Deklarationszeichen (beispielsweise): Dim VarSingle!, Dim VarDouble# ...
[2] Read/Write <=> Datei | Dateinummer (beispielsweise): #DatNum
Die nachgestellten ( ! # ) [1] und das vorangestellte ( # ) [2] Zeichen sind eben auch (im weiteren Sinne) "Schlüsselwörter". Nur diese Zeichen zu finden und zu färben funktioniert eben sehr elegant (und wohl nur) mit "Look-behind"- [1] und "Look-ahead" [2] - Assertionen.
Grüße
Hans-Werner :-))
Sub SearchAndReplace
Dim oWD As Object
Dim oRD As Object
Dim aAttR(0) As New com.sun.star.beans.PropertyValue
oWD = ThisComponent
oRD = oWD.createReplaceDescriptor()
' Look-behind assertion (?<= ... ) - Suche ABCDEF und finde nur DEF:
oRD.SearchString = "(?<=ABC)DEF"
oRD.searchRegularExpression = True
oRD.searchCaseSensitive = True
'oRD.ReplaceString = "$0" ' O.K.
oRD.ReplaceString = "&" ' O.K.
aAttR(0).Name = "CharColor"
aAttR(0).Value = RGB(255,000,000) ' red
oRD.setReplaceAttributes(aAttR())
oWD.replaceAll(oRD)
' Look-ahead assertion (?= ... ) - Suche UVWXYZ und finde nur UVW:
oRD.SearchString = "UVW(?=XYZ)"
oRD.searchRegularExpression = True
oRD.searchCaseSensitive = True
'oRD.ReplaceString = "$0" ' ERROR
'oRD.ReplaceString = "&" ' ERROR
oRD.ReplaceString = "UVW" ' WORKAROUND
aAttR(0).Name = "CharColor"
aAttR(0).Value = RGB(000,000,255) ' blue
oRD.setReplaceAttributes(aAttR())
oWD.replaceAll(oRD)
End Sub