Hallo fr@gma,
In PHP bei preg_match() finde ich immer wieder Formulierungen wie
\K
\K ist eine Escape-Sequenz.
Dort, wo \K
im Suchmuster steht, werden alle bisherigen matches verworfen und der Beginn des matches zurückgesetzt (reset). Natürlich muss aber der Teil vor \K matchen. Falls du dich schon mit lookbehinds beschäftigt hast, diese erfodern meist eine fixe Länge. \K
kann man da sehr gut als Alternative - wie einen Lookbehind mit variabler Länge - verwenden.
Beispiel-String:
The quick brown slug crawls under the lazy dog.
Nun möchte man "slug crawls under" gegen "fox jumps over" ersetzen, aber nur, wenn vorher irgendwo "quick" vorkommt.
Gäbe es einen Lookbehind mit variabler Länge (ev .NET, JGsoft), könnte ein Suchmuster so aussehen:
/(?<=quick.*?)slug crawls under/
Da es diesen aber (bei PHP/PCRE) nicht gibt, könnte man alternativ capturing-groups verwenden
/(quick.*?)slug crawls under/
~~~ und gegen \1 bzw $1 (dem, was der erste geklammerte Ausdruck erfasst hat + neues) ersetzen:
~~~php
\1fox jumps over
Oder aber \K verwenden und an der gewünschten Stelle einfach resetten:
/quick.*?\Kslug crawls under/
Hier muss der erste Teil zwar auch matchen, sobald aber \K erreicht wird, wird der bisherige Teil verworfen. Dagegen ersetzen würde man also lediglich:
fox jumps over
Siehe Beispiel bei regex101.
Die Beispiele sind natürlich unsinng, sollten nur zum Verständnis dienen. Es gibt oft Fälle, bei denen ein bestimmter Teil in einem längeren Suchmuster benötigt wird. \K einfach dorthin, ab wo ersetzt werden soll (alles matchen, aber ab \K ersetzen) bzw ab wo im output benötigt wird.
?:
Mit ?:
nach einer öffnenden Klammer leitet man eine sog. non-capturing group ein.
Sieh mal den Beispiel-String abcdef
und das Suchmuster /a(b(cd|dc))(e)f/
. Dieses enthält 3 geklammerte Bereiche. Standardmäßig sind alle 3 sog. capturing-groups, die intern von links nach rechts numeriert werden: 1.: (b(cd|dc))
2.: (cd|dc)
3.: (e)
. 0 entspricht jeweils dem, was das gesamte Suchmuster matcht.
Im Suchmuster oder Ersetzungsstring könnte man (je nach Sprache) z.b. mit \1
etwas bereits in capturing-group 1 gematchtes weiter integrieren, ausschließen oder ersetzen. Falls eine Funktion verwendet wird, die ein output-array erzeugt, spricht man die von den jeweiligen Gruppen gematchten Teilstrings meist unter den keys ...[1]
, ...[2]
usw an.
Angenommen, es wird nur bcd
, oder bdc
und e
intern, oder im output benötigt, ist die innere capturing-group als solche nicht nötig. /a(b(?:cd|dc))(e)f/
bewirkt das gleiche, enthält aber nur 2 capturing-groups. Siehe Beispiel auf regex101.
Schönen Abend,
Robert