PHP 8.4.1 Released!

Koşullu alt şablonlar

Eşleşme sürecinin, bir savın veya önceki bir yakalayan alt şablonun eşleşme sonucuna bağlı olarak, bir şablona koşullu olarak boyun eğmesi veya iki olasılık arasında seçim yapabilmesi mümkündür. Koşullu alt şablonların olası iki çeşidi şunlardır:

    (?(koşul)evet-şablonu)
    (?(koşul)evet-şablonu|hayır-şablonu)
  

Koşul sağlandığı takdirde evet-şablonu, aksi takdirde hayır-şablonu uygulanır veya hiçbir şablon uygulanmaz. Koşullu alt şablonda ikiden fazla olasılık varsa derleme sırasında hata oluşur.

İki çeşit koşul vardır. Eğer yaylı ayraçlar arasındaki metin rakamlardan oluşuyorsa koşulun içerdiği sayıların önceki yakalayan alt şablonlarla eşleşeceği varsayılır. Şablonu daha okunabilir kılmak için boşluk karakterlerinin yok sayılmakta olduğunu (PCRE_EXTENDED seçeneği) varsayarak boşluklarla üç parçaya bölünmüş şu şablonu ele alalım:

( \( )?    [^()]+    (?(1) \) )

İlk parça bir açan yaylı ayraç ile eşleşir ve karakter mevcut olduğu takdirde bu, ilk yakalayan alt dizge olur. İkinci parça yaylı ayraç olmayan bir veya daha fazla karakterle eşleşir. Üçüncü parça ise bir koşullu alt şablon olarak, ilk yaylı ayraçlı grupla eşleşip eşleşmediğine bakar; eşleşme varsa, yani eşleşmeye konu dizge bir açan yaylı ayraç ile başlıyorsa, koşul doğrulanmış olur. Dolayısıyla evet-şablonu çalıştırılır ve kapatan yaylı ayraç aranır. Aksi takdirde şablon hiçbir şeyle eşleşmez. Başka bir deyişle, bu şablona göre açan yaylı ayraçla başlayan bir dizge kapatan bir yaylı ayraçla bitebileceği gibi bitmeyebilir de.

Eğer koşul olarak (R) dizgesi verilmişse, şablona veya alt şablona ardışık bir çağrı yapılmış gibi ele alınır. "Üst seviye" için koşul daima yanlış sonuç verir.

Eğer koşul rakamlardan veya (R) dizgerinden oluşmuyorsa, bir sav olarak ele alınır.Olumlu veya olumsuz, ileriye veya geriye bakan bir sav olabilir. Yine boşluk karakterlerinin yok sayılacağı varsayımıyla ikinci satırında iki olasılık içeren şu şablonu ele alalım:

    (?(?=[^a-z]*[a-z])
    \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
  

Koşul, ileriye bakan olumlu bir sav olup, isteğe bağlı olarak harf olmayan karakterleri takibeden bir harf ile eşleşir. Başka bir deyişle, eşleşmeye konu dizge içinde en azından bir harfin var olup olmadığına bakar. Eğer bir harf varsa, eşleşmeye konu dizge ilk olasılıkla, aksi takdirde ikinci olasılıkla eşleşir, Şablon, aaa'nın harfleri, dd'nin rakamları ifade ettiği durumda dizgenin ya dd-aaa-dd ya da dd-dd-dd dizilimiyle eşleşecektir.

add a note

User Contributed Notes 1 note

up
3
Anonymous
13 years ago
Repetition of a subpattern will repeat conditionals that are contained inside it, updating subpattern matches with iteration.

Consider the following code, which scans thru HTML, keeping track of angle brackets "<" ">". If open bracket "<" matches, then closing bracket ">" must follow before repetition can possibly end. That way regex will effectively match only outside of tags.

<?php
$pattern
='%(*ANY)(.*?(<)(?(2).*?>)(.*?))*?\'\'%s';
$replace='\1Fred';
$subject=
'<html><body class=\'\'>\'\' went to '\'\meyer and ran
into <b>\'\'</b>.
</body></html>'
echo preg_replace("%(*ANY)(.*?((<)(?(3).*?>).*?)*?)\'\'%s",'\1Fred',$subject);
?>

Output will be:
'<html><body class=\'\'>Fred went to Fredmeyer and ran
into <b>Fred</b>.
</body></html>'
To Top