BasicMakro - Im Kontext RegExp - "Look-ahead assertion" funktionieren "&" bzw. "$0" nicht !

Hallo *,

ich mal wieder mit 'nem BUG-Verdacht :open_mouth: ...

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