Düzenli ifadeler için kullanılabilecek değiştiriciler

Mevcut olası PCRE değiştiricileri aşağıda listelenmiştir. Yaylı ayraçlar içinde belirtilen isimler bu değiştiricilerin dahili PCRE isimleridir. Değiştiricilerdeki boşluklar va satırsonu karakterleri yok sayılır, diğer karakterler ise hataya sebep olur.

i (PCRE_CASELESS)
Bu değiştirici etkin olursa şablondaki harfler hem küçük hem de büyük harflerle eşleşir.
m (PCRE_MULTILINE)
PCRE öntanımlı olarak, eşleşmeye konu dizgeyi karakterlerden oluşan tek bir satır olarak ele alır (satırsonu karakter ile bitmese bile). "Satır başlangıcıyla eşleşme işleci" olan ^ karakteri dizgenin başlangıcıyla, "satır sonuyla eşleşme işleci" olan $ karakteri ise dizgenin sonu ile veya (D değiştiricisi belirtilmedikçe) satırı sonlandıran satırsonu karakterinin öncesiyle eşleşir. Bu. Perl'de de böyledir. Bu değiştiricinin etkin olduğu durumda, satır başı ve satır sonu ile eşleşme işleçleri, dizgenin başı ve sonu ile eşleşmenin yanında satırsonu karakterinin (sırasıyla) sonrası ve öncesiyle de eşleşir. Bu değiştirici Perl'in \m değiştiricisine eşdeğerdir. Eğer eşleşmeye konu dizge "satırsonu karakteri "\n" içermiyorsa veya şablonda ^ veya $ işleçleri kullanılmamışsa bu değiştiricinin bir etkisi olmayacaktır.
s (PCRE_DOTALL)
Bu değiştirici etkin olduğunda şablondaki nokta işleci, satırsonu karakteri dahil tüm karakterlerle eşleşir. Etkin olmadığı takdirde satırsonu karakterleri dışlanır. Bu değiştirici Perl'ün \s değiştiricisine eşdeğerdir. [^a] gibi olumsuz bir sınıf, bu değiştiriciden bağımsız olarak daima satırsonu karateriyle eşleşir.
x (PCRE_EXTENDED)
Bu değiştirici etkin olduğunda şablondaki boşluk karakterleri, öncelenmedikçe veya bir karakter sınıfı içinde yer almadıkça tamamen yoksayıldıkları gibi, bir karakter sınıfının dışında öncelenMEmiş bir # ve sonraki satırsonu karakteri arasındaki karakterlerin tamamı ile satırsonu karakteri de yoksayılır. Bu değiştirici Perl'ün \x değiştiricisine eşdeğerdir ve karmaşık şablonların içine açıklamalar konmasını mümkün kılar. Ancak, bunun sadece veri karakterlerine uygulanmakta oluşuna dikkat ediniz. Boşluk karakterleri, bir şablonda özel karakter dizilimlerinin içinde bulunamazlar; örneğin, bir koşullu alt şablon başlatan (?( dizilimi içinde bulunamazlar.
e (PREG_REPLACE_EVAL)
Bu değiştirici etkin olduğunda, preg_replace() işlevi sonuç dizgesini PHP kodu olarak değerlendirerek normal geriye gönderim ikameleri yapar ve sonucu arama dizgesiyle değiştirmek için kullanır. İkameli geriye gönderimlerdeki tek ve çift tırnaklarla tersbölü ve NULL karakterleri tersbölülerle öncelenir.

Bu değiştiriciyi sadece preg_replace() kullanır; diğer PCRE işlevleri bu değiştiriciyi yok sayar.

A (PCRE_ANCHORED)
Bu değiştirici etkin olduğunda, şablon demirlemeye zolanır yani, şablon eşleşmeye konu dizgenin sadece başlangıcı ile eşleşmeye zorlanır. Bu etki, şablonun içindeki oluşumlarla da sağlanabilir ve Perl'de bunu yapmanın başka yolu yoktur.
D (PCRE_DOLLAR_ENDONLY)
Bu değiştirici etkin olduğunda, şablondaki dolar işleci eşleşmeye konu dizgenin sadece sonu ile eşleşir. Bu değiştirici olmaksızın dolar işleci, satır sonlandıran karakter satırsonu karakteri olduğu takdirde sonuncu satır sonu karakterinin (daha öncekilerin değil) hemen öncesi ile eşleşir. m değiştiricisi etkin olduğunda bu değiştirici yok sayılır. Perl'de bu değiştiricinin eşdeğeri yoktur.
S
Bir şablon defalarca eşleştirilmeye çalışılıyorsa, eşleşme için harcanan zamanı kısaltmak için çözümlemeye harcanan zamanı arttırmak en iyi çözümdür. Bu değiştirici etkin olduğunda ek çözümlemeler yapılır. Halihazırda bu sadece, şablonu tek bir başlangıç karakteriyle eşleşmeye zorlayan demirli şablonlar hariçindeki şablonlar için yararlı olmaktadır.
U (PCRE_UNGREEDY)
Bu değiştirici etkin olduğunda, niceleyicilerin tamahkarlığını tersine çevirir. Böylece, ardlarına bir "?" konmadıkça niceleyiciler öntanımlı olarak tamahkar olmazlar. Bu değiştirici Perl ile uyumlu değildir. Ayrıca, değiştirici şablon içinde de (?U ile) etkin kılılınabileceği gibi niceleyicinin ardına bir soru işareti konarak da (.*? gibi) bu sağlanabilir.
X (PCRE_EXTRA)
Bu değiştirici PCRE'nin Perl ile uyumlu olmayan bir işlevselliğini açıp kapamakta kullanılır. Bir şablonda tersbölü ile öncelenmiş bir karakter özel bir anlama sahip değilse hataya sebep olur. Bu davranış, gelecekteki yorumlamalar için böyle tasarlanmıştır. Perl'de öntanımlı olarak, özel anlamı olmayan tersbölü ile öncelenmiş karakterler kendileri olarak ele alınırlar. Bu değiştiriciden etkilenen bir değiştirici henüz yoktur.
J (PCRE_INFO_JCHANGED)
(?J) dahili seçenek ayarı yerel PCRE_DUPNAMES seçeneğini değiştirerek isimlerin alt şablonlarda tekrarlanmasını mümkün kılar.
u (PCRE_UTF8)
Bu değiştirici PCRE'nin Perl ile uyumlu olmayan bir işlevselliğini etkin kılarak şablon dizgelerinin karakter kodlamasının UTF-8 olduğunun varsayılmasını sağlar. Bu değiştirici Unix türevlerinde PHP 4.1.0'dan beri, win32'de PHP 4.2.3'ten beri kullanılabilmektedir. Şablonun UTF-8 olarak geçerliliği ise PHP 4.3.5 sürümünden beri denetlenmektedir.

add a note add a note

User Contributed Notes 8 notes

up
28
hfuecks at nospam dot org
12 years ago
Regarding the validity of a UTF-8 string when using the /u pattern modifier, some things to be aware of;

1. If the pattern itself contains an invalid UTF-8 character, you get an error (as mentioned in the docs above - "UTF-8 validity of the pattern is checked since PHP 4.3.5"

2. When the subject string contains invalid UTF-8 sequences / codepoints, it basically result in a "quiet death" for the preg_* functions, where nothing is matched but without indication that the string is invalid UTF-8

3. PCRE regards five and six octet UTF-8 character sequences as valid (both in patterns and the subject string) but these are not supported in Unicode ( see section 5.9 "Character Encoding" of the "Secure Programming for Linux and Unix HOWTO" - can be found at http://www.tldp.org/ and other places )

4. For an example algorithm in PHP which tests the validity of a UTF-8 string (and discards five / six octet sequences) head to: http://hsivonen.iki.fi/php-utf8/

The following script should give you an idea of what works and what doesn't;

<?php
$examples
= array(
   
'Valid ASCII' => "a",
   
'Valid 2 Octet Sequence' => "\xc3\xb1",
   
'Invalid 2 Octet Sequence' => "\xc3\x28",
   
'Invalid Sequence Identifier' => "\xa0\xa1",
   
'Valid 3 Octet Sequence' => "\xe2\x82\xa1",
   
'Invalid 3 Octet Sequence (in 2nd Octet)' => "\xe2\x28\xa1",
   
'Invalid 3 Octet Sequence (in 3rd Octet)' => "\xe2\x82\x28",

   
'Valid 4 Octet Sequence' => "\xf0\x90\x8c\xbc",
   
'Invalid 4 Octet Sequence (in 2nd Octet)' => "\xf0\x28\x8c\xbc",
   
'Invalid 4 Octet Sequence (in 3rd Octet)' => "\xf0\x90\x28\xbc",
   
'Invalid 4 Octet Sequence (in 4th Octet)' => "\xf0\x28\x8c\x28",
   
'Valid 5 Octet Sequence (but not Unicode!)' => "\xf8\xa1\xa1\xa1\xa1",
   
'Valid 6 Octet Sequence (but not Unicode!)' => "\xfc\xa1\xa1\xa1\xa1\xa1",
);

echo
"++Invalid UTF-8 in pattern\n";
foreach (
$examples as $name => $str ) {
    echo
"$name\n";
   
preg_match("/".$str."/u",'Testing');
}

echo
"++ preg_match() examples\n";
foreach (
$examples as $name => $str ) {
   
   
preg_match("/\xf8\xa1\xa1\xa1\xa1/u", $str, $ar);
    echo
"$name: ";

    if (
count($ar) == 0 ) {
        echo
"Matched nothing!\n";
    } else {
        echo
"Matched {$ar[0]}\n";
    }
   
}

echo
"++ preg_match_all() examples\n";
foreach (
$examples as $name => $str ) {
   
preg_match_all('/./u', $str, $ar);
    echo
"$name: ";
   
   
$num_utf8_chars = count($ar[0]);
    if (
$num_utf8_chars == 0 ) {
        echo
"Matched nothing!\n";
    } else {
        echo
"Matched $num_utf8_chars character\n";
    }
   
}
?>
up
11
Daniel Klein
5 years ago
If the _subject_ contains utf-8 sequences the 'u' modifier should be set, otherwise a pattern such as /./ could match a utf-8 sequence as two to four individual ASCII characters. It is not a requirement, however, as you may have a need to break apart utf-8 sequences into single bytes. Most of the time, though, if you're working with utf-8 strings you should use the 'u' modifier.

If the subject doesn't contain any utf-8 sequences (i.e. characters in the range 0x00-0x7F only) but the pattern does, as far as I can work out, setting the 'u' modifier would have no effect on the result.
up
11
phpman at crustynet dot org dot uk
6 years ago
The description of the "u" flag is a bit misleading. It suggests that it is only required if the pattern contains UTF-8 characters, when in fact it is required if either the pattern or the subject contain UTF-8. Without it, I was having problems with preg_match_all returning invalid multibyte characters when given a UTF-8 subject string.

It's fairly clear if you read the documentation for libpcre:

       In  order  process  UTF-8 strings, you must build PCRE to include UTF-8
       support in the code, and, in addition,  you  must  call  pcre_compile()
       with  the  PCRE_UTF8  option  flag,  or the pattern must start with the
       sequence (*UTF8). When either of these is the case,  both  the  pattern
       and  any  subject  strings  that  are matched against it are treated as
       UTF-8 strings instead of strings of 1-byte characters.

[from http://www.pcre.org/pcre.txt]
up
7
michal dot kocarek at brainbox dot cz
8 years ago
In case you're wondering, what is the meaning of "S" modifier, this paragraph might be useful:

When "S" modifier is set, PHP calls the pcre_study() function from the PCRE API before executing the regexp. Result from the function is passed directly to pcre_exec().

For more information about pcre_study() and "Studying the pattern" check the PCRE manual on http://www.pcre.org/pcre.txt

PS: Note that function names "pcre_study" and "pcre_exec" used here refer to PCRE library functions written in C language and not to any PHP functions.
up
6
varrah NO_GARBAGE_OR_SPAM AT mail DOT ru
12 years ago
Spent a few days, trying to understand how to create a pattern for Unicode chars, using the hex codes. Finally made it, after reading several manuals, that weren't giving any practical PHP-valid examples. So here's one of them:

For example we would like to search for Japanese-standard circled numbers 1-9 (Unicode codes are 0x2460-0x2468) in order to make it through the hex-codes the following call should be used:
preg_match('/[\x{2460}-\x{2468}]/u', $str);

Here $str is a haystack string
\x{hex} - is an UTF-8 hex char-code
and /u is used for identifying the class as a class of Unicode chars.

Hope, it'll be useful.
up
4
ebarnard at marathonmultimedia dot com
10 years ago
When adding comments with the /x modifier, don't use the pattern delimiter in the comments. It may not be ignored in the comments area. Example:

<?php
$target
= 'some text';
if(
preg_match('/
                e # Comments here
               /x'
,$target)) {
    print
"Target 1 hit.\n";
}
if(
preg_match('/
                e # /Comments here with slash
               /x'
,$target)) {
    print
"Target 1 hit.\n";
}
?>

prints "Target 1 hit." but then generates a PHP warning message for the second preg_match():

Warning:  preg_match() [function.preg-match]: Unknown modifier 'C' in /ebarnard/x-modifier.php on line 11
up
0
damian dot driscoll at gmail dot com
2 months ago
The PCRE_INFO_JCHANGED modifier works in version 5.6.31 but not in 5.6.16, which generates an 'unknown modifier J' warning.
up
0
arash dot dalir at gmail dot com
2 months ago
the PCRE_INFO_JCHANGED modifier is apparently not accepted as a global option (after the closing delimiter) in PHP versions <= 5.4 (not checked in PHP 5.5) but allowed in PHP 5.6 (also not checked in PHP 7.X)

The following pattern doesn't work in PHP 5.4, but it works in PHP 5.6:

<?php
//test.php
preg_match_all('/(?<dup_name>\d{1,4})\-(?<dup_name>\d{1,2})/J', '1234-23', $matches);
var_dump($matches);

/*
output in PHP 5.4:
Warning: preg_match_all(): Unknown modifier 'J' in test.php on line 3
NULL
--------------
output PHP 5.6:
array(4) {
    [0]=> array(1)  { [0]=> string(7) "1234-23" }
    ["dup_name"]=> array(1) { [0]=> string(2) "23" }
    [1]=> array(1) { [0]=> string(4) "1234" }
    [2]=> array(1) { [0]=> string(2) "23" }
}
*/
?>

in order to resolve this issue in PHP 5.4, one can use the (?J) pattern modifier, which indicates the pattern (from that point forward) allows duplicate names for subpatterns.

code which works in PHP 5.4:
<?php

preg_match_all
('/(?J)(?<dup_name>\d{1,4})\-(?<dup_name>\d{1,2})/', '1234-23', $matches);
var_dump($matches);

/*
output in PHP 5.4:
array(4) {
    [0]=> array(1) { [0]=> string(7) "1234-23" }
    ["dup_name"]=> array(1) { [0]=> string(2) "23" }
    [1]=> array(1) { [0]=> string(4) "1234" }
    [2]=> array(1) { [0]=> string(2) "23" }
}
--------------
output in PHP 5.6 (the same as with /J):
array(4) {
    [0]=> array(1)  { [0]=> string(7) "1234-23" }
    ["dup_name"]=> array(1) { [0]=> string(2) "23" }
    [1]=> array(1) { [0]=> string(4) "1234" }
    [2]=> array(1) { [0]=> string(2) "23" }
}
*/
?>
To Top