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.

Um eine Callout-Funktion bereitzustellen, muss sie entweder formell definiert oder einer Variable innerhalb des Gültigkeitsbereichs der Funktion (lokal oder global) zugewiesen werden, die RegExMatch oder RegExReplace aufgerufen hat. Wenn Funktion weggelassen wird, wird standardmäßig pcre_callout verwendet. Wenn keine Variable gefunden wird oder ihr Wert kein Funktionsobjekt ist, wird ein Fehler ausgelöst.

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.