"line break" is ill-defined:
-- Windows uses CR+LF (\r\n)
-- Linux LF (\n)
-- OSX CR (\r)
Little-known special character:
\R in preg_* matches all three.
preg_match( '/^\R$/', "match\nany\\n\rline\r\nending\r" ); // match any line endings
Tersbölü karakterinin çeşitli kullanımları vardır. Tersbölünün ilk kullanım çeşidinde, bir harfin veya bir rakamın soluna konmuşsa karakterin özel anlamını kaldırır; karakter sınıflarının içinde ve dışında bir önceleme karakteri olarak iş görür.
Örneğin, şablonunuzun "*" karakteri ile eşleşmesini isterseniz, şablonu "\*" biçiminde yazmalısınız. Tersbölü karakterinin öncelediği karakter bir düzenli ifade işleci olsun ya da olmasın yorumu değişmeyecek, daima öncelediği karakter kendisiyle eşleşecektir. Sonuç olarak, önceleme işleci harf veya rakam olmayan karakterlerle de güvenle kullanılabilmektedir. Özellikle, bir tersbölü karakteri ile eşleşme sağlamak için "\\" yazmalısınız.
Bilginize:
Tek ve çift tırnaklı PHP dizeleri içinde tersbölü karakteri özel olarak ele alınır. Bir \ ile eşleşen \\ düzenli ifadesi, PHP kodu içinde "\\\\" veya '\\\\' olarak belirtilmelidir.
Bir şablon PCRE_EXTENDED seçeneği ile derlenmişse kalıp içindeki (bir karakter sınıfının dışında kalan) boşluk karakterleri ve bir karakter sınıfının dışındaki bir "#" karakteri ile sonraki satırsonu karakteri arasındaki karakterler yok sayılır. Bir boşluk veya "#" karakterini şablonun parçası haline getirmek için, karakter tersbölü ile öncelenir.
Tersbölü karakterinin ikinci kullanımı, basılamayan karakterleri şablon içinde görünür kılmak içindir. İkil sıfırın şablonu sonlandırması dışında basılamayan karakterlerin görünümü ile ilgili bir kısıtlama yoktur. Fakat, bir şablon, bir metni düzenleyerek hazırlanıyorsa aşağıdaki önceleme dizilimlerini kullanmak, ifade ettikleri ikil karakterleri kullanmaktan daha kolaydır:
"\cx
" diziliminin en hassas etkisi şöyledir:
"x
" bir küçük harf ise büyük harfe dönüştürülür ve
karakterin 6. biti (onaltılık 40) evrilir. Böylece,
"\cz
" dizilimi onaltılık 1A haline gelirken
"\c{
" onaltılık 3B ve "\c;
"
onaltılık 7B haline gelir.
"\x
" dizilimden sonra en fazla iki onaltılık rakam
okunur (harfler büyük veya küçük olabilir). UTF-8
kipinde, "\x{...}
" gösterimine izin
verilir; kaşlı ayraçların arasına yazılan onaltılık sayı UTF-8
karakterin kodu olarak yorumlanır. Özgün onaltılık önceleme dizilimi
\xhh
, eğer karakterin kodu 127'den büyükse iki
baytlık bir UTF-8 karakteri ile eşleşecektir.
"\0
" dizilimden sonra en fazla iki sekizlik rakam
okunur. Her iki durumda da, iki rakamdan azı varsa olanlar kullanılır.
Böylece, "\0\x\07
" dizilimi iki ikil sıfırdan sonra
bir BEL karakteri olarak yorumlanır. Eğer sekizlik gösterimin hemen
ardından sekizlik rakam olarak yorumlanabilecek bir karakter geliyorsa
ilk sıfırdan sonra mutlaka iki sekizlik rakam kullanın.
Tersbölünün hemen ardından 0 haricinde bir rakam gelmesi durumunda durum biraz karışır. Bir karakter sınıfının dışında, PCRE o rakamı ve diğer rakamları bir onluk sayı olarak okur. Eğer sayı 10'dan küçükse veya evvelce belirtilmiş yakalayan alt şablonlar varsa dizilimin tamamı bir geriye gönderim olarak ele alınır. İkinci durumun nasıl çalıştığı aşağıda parantezli alt şablonların açıklamasında anlatılmıştır.
Bir karakter sınıfının içinde veya evvelinde yakalayan alt şablonlar bulunmayan 9'dan büyük bir onluk sayı varlığında PCRE tersbölüden sonra en fazla üç sekizlik rakam okur ve değerin en önemsiz 8 bitinden tek bir bayt üretir. Daha sonraki rakamlar karakterlerin kendileri olarak ele alınır. Örnekler:
100'den büyük sekizlik değerlerin başına sıfır konmamalıdır, çünkü üç sekizlik rakamdan fazlası sekizlik sayının rakamları olarak ele alınmamaktadır.
Tek bir bayt değerini tanımlayan tüm dizilimler karakter sınıflarının
içinde de dışında da kullanılabilir. Ek olarak, bir karakter sınıfının
içinde, "\b
" dizilimi bir tersbölü karakteri
(onaltılık 08) olarak yorumlanır. Karakter sınıfının dışında ise anlamı
farklıdır (aşağıya bakınız).
Tersbölünün üçüncü kullanımı soysal karakter türlerini belirtmek içindir:
Her önceleme dizilimi çifti karakter kümesinin tamamını iki ayrı küme haline getirir. Belirtilen her karakter sadece ve sadece bir çift ile eşleşir.
"Boşluk" karakterleri HT (9), LF (10), FF (12), CR (13) ve boşluktur (32). Bununla birlikte, yerele özgü eşleştirme gerçekleşiyorsa, 128-255 aralığındaki kodlar sahip karakterler de boşluk karakterleri olarak kabul edilebilir, örneğin, NBSP (A0).
Bir "sözcük" karakteri herhangi bir harf, rakam veya alt çizgi karakteri
olabilir, yani, bir Perl sözcüğünün parçası olabilen her karakter bir
"sözcük" karakteri olabilir. Harflerin ve rakamların tanımı PCRE'nin
karakter tablosu tarafından denetlenir ve eşleştirme yerele özgü
yapılıyorsa bu tanım değişebilir. Örneğin "tr" yerelindeki 128'den büyük
karakter koduna sahip "çğıöşü" gibi karakterler \w
ile eşleşir.
Karakter türündeki bu dizilimler karakter sınıflarının içinde veya dışında bulunabilir. Her biri uygun türdeki bir karakterle eşleşir. Eğer karakter eşleştirmesinde eşleşmeye konu dizgenin sonuna gelinmişse hiçbir karakter eşleşmeyeceğinden işlem başarısız olacaktır.
Tersbölünün dördüncü kullanımı bazı basit tezleri belirtmek içindir. Bir tez, eşleşmeye konu dizgenin hiçbir karakterini harcamaksızın belli bir noktada yerine getirilmesi gereken bir koşul belirtir. Daha karmaşık tezler için alt şablonların kullanımı aşağıda açıklanmıştır. Tez işleçleri şunlardır:
Bu tez işleçleri "\b
" hariç karakter sınıfları içinde
görünmezler. "\b
" işleci karakter sınıfları içinde
özel bir anlama sahiptir ve tersbölü karaterini simgeler.
Eşleşmeye konu dizge içinde geçerli karakterin \w
işleci ile ve önceki karakterin \W
işleci ile
eşleştiği nokta sözcük sınırının başlangıcını; geçerli karakterin
\W
işleci ile ve önceki karakterin
\w
işleci ile eşleştiği nokta ise sözcük sınırının
bitişini belirler.
\A
, \Z
ve
\z
tez işleçleri, seçeneklerle belirlenen şekilde
dizgenin en başı ve dizgenin en sonu ile eşleşen geleneksel şapka ve
dolar imli işleçlerden
(çıpalar altında
açıklanmıştır) farklı olup
PCRE_MULTILINE
veya
PCRE_DOLLAR_ENDONLY seçeneğinden etkilenmezler.
\Z
ile \z
arasındaki fark
\Z
işlecinin dizgenin son karakteri olan satırsonu
karakterinin öncesiyle eşleşmesi, \z
işlecinin ise
sadece dizge sonu ile eşleşmesidir.
\G
savı, sadece, geçerli eşleşme konumu eşleşmenin
başlangıç noktasında (preg_match() işlevinin
başlangıç
bağımsız değişkeni ile belirtilen noktada)
olduğu takdirde doğru olacaktır. başlangıç
sıfırdan farklı olduğu durumda \G
işleci
\A
işlecinden farklıdır.
\Q
ve \E
işleçleri şablon içindeki düzenli ifade işleçlerini geçersiz kılmak
için kullanılabilmektedir. Örneğin, \w+\Q.$.\E$
düzenli ifadesi dizge sonuna demirlenmiş .$.
karakterleriyle ve bunların öncesindeki bir veya daha fazla sayıda
sözcük karakteriyle eşleşecektir. Bu, ayraçların davranışını değiştirmez.
Örneğin, #\Q#\E#$
düzenli ifadesi, ikinci
#
şablonun sonunu imlediğinden ve
\E#
geçersiz değiştirici olarak yorumlandığından
geçersizdir.
\K
işleci eşleşme
başlangıcını sıfırlamak için kullanılabilmektedir. Örneğin,
foo\Kbar
şablonu, "foobar" ile eşleşir, fakat "bar"
ile eşleştiğini raporlar. \K
işlecinin kullanımı
zaten eşleştirilmiş alt dizge ile etkileşmez. Örneğin,
(foo)\Kbar
şablonu "foobar" ile eşleşirken eşleşen
ilk alt dizge "foo" olacaktır.
"line break" is ill-defined:
-- Windows uses CR+LF (\r\n)
-- Linux LF (\n)
-- OSX CR (\r)
Little-known special character:
\R in preg_* matches all three.
preg_match( '/^\R$/', "match\nany\\n\rline\r\nending\r" ); // match any line endings
Significantly updated version (with new $pat4 utilising \R properly, its results and comments):
Note that there are (sometimes difficult to grasp at first glance) nuances of meaning and application of escape sequences like \r, \R and \v - none of them is perfect in all situations, but they are quite useful nevertheless. Some official PCRE control options and their changes come in handy too - unfortunately neither (*ANYCRLF), (*ANY) nor (*CRLF) is documented here on php.net at the moment (although they seem to be available for over 10 years and 5 months now), but they are described on Wikipedia ("Newline/linebreak options" at https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions) and official PCRE library site ("Newline convention" at http://www.pcre.org/original/doc/html/pcresyntax.html#SEC17) pretty well. The functionality of \R appears somehow disappointing (with default configuration of compile time option) according to php.net as well as official description ("Newline sequences" at https://www.pcre.org/original/doc/html/pcrepattern.html#newlineseq) when used improperly.
A hint for those of you who are trying to fight off (or work around at least) the problem of matching a pattern correctly at the end ($) of any line in multiple lines mode (/m).
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
// C 3 p 0 _
$pat1='/\w$/mi'; // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi'; // Slightly better
$pat3='/\w\R?$/mi'; // Somehow disappointing according to php.net and pcre.org when used improperly
$pat4='/\w(?=\R)/i'; // Much better with allowed lookahead assertion (just to detect without capture) without multiline (/m) mode; note that with alternative for end of string ((?=\R|$)) it would grab all 7 elements as expected
$pat5='/\w\v?$/mi';
$pat6='/(*ANYCRLF)\w$/mi'; // Excellent but undocumented on php.net at the moment (described on pcre.org and en.wikipedia.org)
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
$t=preg_match_all($pat6, $str, $m6);
echo $str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
."\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
."\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
."\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
."\n5 !!! $pat5 ($s): ".print_r($m5[0], true)
."\n6 !!! $pat6 ($t): ".print_r($m6[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 and $pat4 (\R), $pat5 (\v) and altered newline option in $pat6 ((*ANYCRLF)) - for some applications at least.
/* The code above results in the following output:
ABC ABC
123 123
def def
nop nop
890 890
QRS QRS
~-_ ~-_
1 !!! /\w$/mi (3): Array
(
[0] => C
[1] => 0
[2] => _
)
2 !!! /\w\r?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
3 !!! /\w\R?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
4 !!! /\w(?=\R)/i (6): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
)
5 !!! /\w\v?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
6 !!! /(*ANYCRLF)\w$/mi (7): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
[6] => _
)
*/
?>
Unfortunately, I haven't got any access to a server with the latest PHP version - my local PHP is 5.3.8 and my public host's PHP is version 5.2.17.
A non breaking space is not considered as a space and cannot be caught by \s.
it can be found with :
- [\xc2\xa0] in utf-8
- \x{00a0} in unicode
As \v matches both single char line ends (CR, LF) and double char (CR+LF, LF+CR), it is not a fixed length atom (eg. is not allowed in lookbehind assertions).
Note that there are (sometimes difficult to grasp at first glance) nuances of meaning and application of escape sequences like \r, \R and \v - none of them is perfect in all situations, but they are quite useful nevertheless. Some official PCRE control options and their changes come in handy too - unfortunately neither (*ANYCRLF), (*ANY) nor (*CRLF) is documented here on php.net at the moment (although they seem to be available for over 10 years and 5 months now), but they are described on Wikipedia ("Newline/linebreak options" at https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions) and official PCRE library site ("Newline convention" at http://www.pcre.org/original/doc/html/pcresyntax.html#SEC17) pretty well. The functionality of \R appears somehow disappointing (with default configuration of compile time option) according to php.net as well as official description ("Newline sequences" at https://www.pcre.org/original/doc/html/pcrepattern.html#newlineseq).
A hint for those of you who are trying to fight off (or work around at least) the problem of matching a pattern correctly at the end ($) of any line in multiple lines mode (/m).
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
// C 3 p 0 _
$pat1='/\w$/mi'; // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi';
$pat3='/\w\R?$/mi'; // Somehow disappointing according to php.net and pcre.org
$pat4='/\w\v?$/mi';
$pat5='/(*ANYCRLF)\w$/mi'; // Excellent but undocumented on php.net at the moment
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
echo $str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
."\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
."\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
."\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
."\n5 !!! $pat5 ($s): ".print_r($m5[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 (\R), $pat4 (\v) and altered newline option in $pat5 ((*ANYCRLF)) - for some applications at least.
/* The code above results in the following output:
ABC ABC
123 123
def def
nop nop
890 890
QRS QRS
~-_ ~-_
1 !!! /\w$/mi (3): Array
(
[0] => C
[1] => 0
[2] => _
)
2 !!! /\w\r?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
3 !!! /\w\R?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
4 !!! /\w\v?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)
5 !!! /(*ANYCRLF)\w$/mi (7): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
[6] => _
)
*/
?>
Unfortunately, I haven't got any access to a server with the latest PHP version - my local PHP is 5.3.8 and my public host's PHP is version 5.2.17.