Callouts in Regulären Ausdrücken

RegEx-Callouts bieten die Möglichkeit, die Kontrolle vorübergehend an das Skript zu übergeben, während ein regulärer Ausdruck ausgewertet wird. Detaillierte Informationen über das PCRE-Standard-Callout-Feature finden Sie unter pcre.txt.

RegEx-Callouts werden zurzeit nur von RegExMatch und RegExReplace unterstützt.

Inhaltsverzeichnis

Syntax

Die Syntax für ein RegEx-Callout ist (?CNummer:Funktion), wobei sowohl Nummer als auch Funktion optional sind. Der Doppelpunkt (:) ist nur erlaubt, wenn Funktion angegeben ist, und optional, wenn Nummer weggelassen wird. Wenn Funktion angegeben ist, aber nicht der Name eines Funktionsobjekts ist, wird ein Kompilierungsfehler auftreten und die Suchmusterauswertung abgebrochen.

Wenn Funktion weggelassen wird, muss die Standard-RegEx-Callout-Funktion namens pcre_callout definiert werden. Wenn pcre_callout nicht definiert ist, werden RegEx-Callouts ohne Funktion ignoriert.

RegEx-Callout-Funktionen

MeineFunktion(Match, CalloutNummer, FundPos, Heuhaufen, NadelRegEx)
{
    ...
}

RegEx-Callout-Funktionen akzeptieren bis zu 5 Parameter:

Diese Namen sind nur Beispiele. Es können beliebige Namen verwendet werden.

Warnung: Das Ändern der Eingabeparameter von RegExReplace oder RegExMatch während eines Aufrufs wird nicht unterstützt und kann zu unvorhersehbarem Verhalten führen.

Die Suchmusterauswertung kann je nach Rückgabewert der RegEx-Callout-Funktion fortgesetzt werden oder fehlschlagen:

Zum Beispiel:

Heuhaufen := "The quick brown fox jumps over the lazy dog."
RegExMatch(Heuhaufen, "i)(The) (\w+)\b(?CCallout)")
Callout(m, *) {
    MsgBox "m[0]=" m[0] "`nm[1]=" m[1] "`nm[2]=" m[2]
    return 1
}

Im obigen Beispiel wird Callout einmal für jede Teilzeichenkette aufgerufen, die mit dem Teil des Suchmusters vor dem RegEx-Callout übereinstimmt. Das \b wird verwendet, um unvollständige Wörter in Übereinstimmungen wie The quic, The qui, The qu, etc. auszuschließen.

Wenn einer der Eingabeparameter einer RegEx-Funktion während eines Callouts geändert wird, ist das Verhalten undefiniert.

EventInfo

Zusätzliche Informationen erhalten Sie durch Zugriff auf die pcre_callout_block-Struktur via A_EventInfo.

version           := NumGet(A_EventInfo,  0, "Int")
callout_number    := NumGet(A_EventInfo,  4, "Int")
offset_vector     := NumGet(A_EventInfo,  8, "Ptr")
subject           := NumGet(A_EventInfo,  8 + A_PtrSize, "Ptr")
subject_length    := NumGet(A_EventInfo,  8 + A_PtrSize*2, "Int")
start_match       := NumGet(A_EventInfo, 12 + A_PtrSize*2, "Int")
current_position  := NumGet(A_EventInfo, 16 + A_PtrSize*2, "Int")
capture_top       := NumGet(A_EventInfo, 20 + A_PtrSize*2, "Int")
capture_last      := NumGet(A_EventInfo, 24 + A_PtrSize*2, "Int")
pad := A_PtrSize=8 ? 4 : 0  ; Ausgleich für die 64-Bit-Datenausrichtung.
callout_data      := NumGet(A_EventInfo, 28 + pad + A_PtrSize*2, "Ptr")
pattern_position  := NumGet(A_EventInfo, 28 + pad + A_PtrSize*3, "Int")
next_item_length  := NumGet(A_EventInfo, 32 + pad + A_PtrSize*3, "Int")
if (version >= 2)
    mark   := StrGet(NumGet(A_EventInfo, 36 + pad + A_PtrSize*3, "Int"), "UTF-8")

Weitere Informationen finden Sie unter pcre.txt, NumGet und A_PtrSize.

Auto-Callout

Fügen Sie C in die Optionen des Suchmusters ein, um den Auto-Callout-Modus zu aktivieren. In diesem Modus werden RegEx-Callouts äquivalent zu (?C255) vor jedem Element im Suchmuster eingefügt. Das folgende Beispiel kann zum Debuggen von regulären Ausdrücken verwendet werden:

; RegExMatch mit der Auto-Callout-Option C aufrufen.
RegExMatch("xxxabc123xyz", "C)abc.*xyz")

; Standard-RegEx-Callout-Funktion definieren.
pcre_callout(Match, CalloutNumber, FoundPos, Haystack, NeedleRegEx)
{
    ; Beschreibungen dieser Felder finden Sie unter pcre.txt.
    start_match       := NumGet(A_EventInfo, 12 + A_PtrSize*2, "Int")
    current_position  := NumGet(A_EventInfo, 16 + A_PtrSize*2, "Int")
    pad := A_PtrSize=8 ? 4 : 0
    pattern_position  := NumGet(A_EventInfo, 28 + pad + A_PtrSize*3, "Int")
    next_item_length  := NumGet(A_EventInfo, 32 + pad + A_PtrSize*3, "Int")

    ; Aktuelle Übereinstimmung >>hervorheben<<.
    _HAYSTACK:=SubStr(Haystack, 1, start_match)
        . ">>" SubStr(Haystack, start_match + 1, current_position - start_match)
        . "<<" SubStr(Haystack, current_position + 1)
    
    ; Nächstes auszuwertendes Element >>hervorheben<<.
    _NEEDLE:=  SubStr(NeedleRegEx, 1, pattern_position)
        . ">>" SubStr(NeedleRegEx, pattern_position + 1, next_item_length)
        . "<<" SubStr(NeedleRegEx, pattern_position + 1 + next_item_length)
    
    ListVars
    ; Drücken Sie PAUSE, um fortzufahren.
    Pause
}

Bemerkungen

RegEx-Callouts werden im aktuellen Pseudo-Thread ausgeführt, allerdings wird der vorherige Wert von A_EventInfo wiederhergestellt, wenn die RegEx-Callout-Funktion zurückkehrt.

PCRE ist so optimiert, dass es in einigen Fällen vorzeitig abbricht, wenn es feststellt, dass eine Übereinstimmung nicht möglich ist. Um in solchen Fällen RegEx-Callouts zu ermöglichen, müssen diese Optimierungen durch Angabe von (*NO_START_OPT) am Anfang des Suchmusters deaktiviert werden.