PHP 8.4.2 Released!

Geriye Gönderimler

Bir karakter sınıfının dışında, bir tersbölü ile öncelenmiş 0'dan büyük bir sayı, şablonda kendinden önce yaylı ayraçlarla gruplanmış alt şablonlar varsa, bunlar arasından kendisiyle ilgili yakalayan alt şablona gönderim olarak ele alınır.

Ancak, tersbölüyü takibeden onluk sayı 10'dan küçükse, bu daima bir geriye gönderim olarak ele alınır ve şablonun öncesinde bir yakalayan alt şablon başlatan bundan daha az sayıda yaylı ayraç varsa işlem bir hata ile sonuçlanır. Başka bir deyişle, 10'dan küçük numaralı yakalayan alt şablonları kapatan ayraçların kendileriyle ilgili geriye gönderimlerin öncesinde bulunma koşulu yoktur. Tersbölüyü takibeden rakamların ele alınışları ile ilgili ayrıntılı bilgiyi önceleme karakteri bölümünde bulabilirsiniz.

Bir geriye gönderimin eşleştiği alt şablon olasılıklar içeriyorsa, geriye gönderim, şablonun kalanının eşleştiği olasılıktan başka bir olasılıkla eşleşmez. Yani, (sens|respons)e and \1ibility şablonu, "sense and sensibility" ve "response and responsibility" ile eşleştiği halde "sense and responsibility" ile eşleşmeyecektir. Harf büyüklüğüne duyarlılık etkin olduğunda geriye gönderim de aynı duyarlılığa sahip olacaktır. Örneğin, ((?i)rah)\s+\1 şablonunda, yakalayan alt şablon özgün olarak harf büyüklüğüne duyarlı eşleştiği halde bile "rah rah" ve "RAH RAH" ile eşleşecek ama "RAH rah" ile eşleşmeyecektir.

Aynı alt şablon için birden fazla geriye gönderim olabilir. Bir şablonun eşleşeceği bir dizge parçası yoksa onunla ilgili geriye gönderimler daima başarısız olacaktır. Örneğin, (a|(bc))\2 şablonu "bc" yerine "a" ile başlayan bir dizgeyle başarısız olacaktır. 99 ayrı geriye gönderim olabileceğinden bir tersbölüyü takibeden tüm rakamlar olası bir geriye gönderim olarak ele alınacaktır. Eğer alt şablon bir rakam karakteri ile devam ediyorsa geri gönderimi sonlandırmak için bir ayraç karakteri gerekir. PCRE_EXTENDED seçeneği etkinse bu ayraç karakteri, boşluk karakteridir. Aksi takdirde boş bir açıklama kullanmak gerekir.

Yaylı ayraçların içinde kullanılan bir geriye gönderim, ilgili alt şablonun hemen ardından kullanılmışsa başarısız olacaktır. Bu bakımdan, örneğin (a\1) şablonu hiçbir dizgeyle eşleşmeyecektir. Bununla birlikte, böyle alt şablon içindeki geriye gönderimler bazı durumlarda oldukça kullanışlı olabilir. Örneğin, (a|b\1)+ şablonu herhangi bir sayıda "a" veya "aba" ya da "ababba" ve benzeri dizgesiyle eşleşecektir. Alt şablonun her yinelenişinde, geriye gönderim kendisiyle ilişkili alt dizge ile eşleşecektir. Bunun çalışması için, ilk yinelemenin geriye gönderimle eşleşmesi gerekli değildir. Bu, yukarıdaki gibi olasılık belirtimiyle veya asgarisi sıfır olan bir yineleyici kullanılarak yapılabilir.

İsimli alt şablonlara gerigönderimler (?P=ad), \k<ad>, \k'ad', \k{ad}, \g{ad}, \g<ad> veya \g'ad' ile sağlanabilir.

add a note

User Contributed Notes 2 notes

up
13
mnvx at yandex dot ru
8 years ago
Something similar opportunity is DEFINE.

Example:
(?(DEFINE)(?<myname>\bvery\b))(?&myname)\p{Pd}(?&myname).

Expression above will match "very-very" from next sentence:
Define is very-very handy sometimes.
^-------^

How it works. (?(DEFINE)(?<myname>\bvery\b)) - this block defines "myname" equal to "\bvery\b". So, this block "(?&myname)\p{Pd}(?&myname)" equvivalent to "\bvery\b\p{Pd}\bvery\b".
up
0
Steve
2 years ago
The escape sequence \g used as a backreference may not always behave as expected.
The following numbered backreferences refer to the text matching the specified capture group, as documented:
\1
\g1
\g{1}
\g-1
\g{-1}

However, the following variants refer to the subpattern code instead of the matched text:
\g<1>
\g'1'
\g<-1>
\g'-1'

With named backreferences, we may also use the \k escape sequence as well as the (?P=...) construct. The following combinations also refer to the text matching the named capture group, as documented:
\g{name}
\k{name}
\k<name>
\k'name'
(?P=name)

However, these refer to the subpattern code instead of the matched text:
g<name>
\g'name'

In the following example, the capture group searches for a single letter 'a' or 'b', and then the backreference looks for the same letter. Thus, the patterns are expected to match 'aa' and 'bb', but not 'ab' nor 'ba'.

<?php
/* Matches to the following patterns are replaced by 'xx' in the subject string 'aa ab ba bb'. */
$patterns = [
# numbered backreferences (absolute)
'/([ab])\1/', // 'xx ab ba xx'
'/([ab])\g1/', // 'xx ab ba xx'
'/([ab])\g{1}/', // 'xx ab ba xx'
'/([ab])\g<1>/', // 'xx xx xx xx' # unexpected behavior, backreference matches both 'a' and 'b'.
"/([ab])\g'1'/", // 'xx xx xx xx' # unexpected behavior, backreference matches both 'a' and 'b'.
'/([ab])\k{1}/', // 'aa ab ba bb' # No group with name "1", backreference to unset group always fails.
'/([ab])\k<1>/', // 'aa ab ba bb' # No group with name "1", backreference to unset group always fails.
"/([ab])\k'1'/", // 'aa ab ba bb' # No group with name "1", backreference to unset group always fails.
'/([ab])(?P=1)/', // NULL # Regex error: "subpattern name must start with a non-digit", (?P=) expects name not number.
# numbered backreferences (relative)
'/([ab])\-1/', // 'aa ab ba bb'
'/([ab])\g-1/', // 'xx ab ba xx'
'/([ab])\g{-1}/', // 'xx ab ba xx'
'/([ab])\g<-1>/', // 'xx xx xx xx' # unexpected behavior, backreference matches both 'a' and 'b'.
"/([ab])\g'-1'/", // 'xx xx xx xx' # unexpected behavior, backreference matches both 'a' and 'b'.
'/([ab])\k{-1}/', // 'aa ab ba bb' # No group with name "-1", backreference to unset group always fails.
'/([ab])\k<-1>/', // 'aa ab ba bb' # No group with name "-1", backreference to unset group always fails.
"/([ab])\k'-1'/", // 'aa ab ba bb' # No group with name "-1", backreference to unset group always fails.
'/([ab])(?P=-1)/', // NULL # Regex error: "subpattern name expected", (?P=) expects name not number.
# named backreferences
'/(?<name>[ab])\g{name}/', // 'xx ab ba xx'
'/(?<name>[ab])\g<name>/', // 'xx xx xx xx' # unexpected behavior, backreference matches both 'a' and 'b'.
"/(?<name>[ab])\g'name'/", // 'xx xx xx xx' # unexpected behavior, backreference matches both 'a' and 'b'.
'/(?<name>[ab])\k{name}/', // 'xx ab ba xx'
'/(?<name>[ab])\k<name>/', // 'xx ab ba xx'
"/(?<name>[ab])\k'name'/", // 'xx ab ba xx'
'/(?<name>[ab])(?P=name)/', // 'xx ab ba xx'
];

foreach (
$patterns as $pat)
echo
" '$pat',\t// " . var_export(@preg_replace($pat, 'xx', 'aa ab ba bb'), 1) . PHP_EOL;
?>
To Top