|
 |
Модификаторы шаблоновМодификаторы шаблонов -- Описывает возможные модификаторы шаблонов Perl-совместимых регулярных выражений (PCRE) Описание
Ниже перечислены все доступные на сегодняшний день модификаторы.
Имя, взятое в круглые скобки, указывает внутреннее PCRE имя для данного модификатора.
- i (PCRE_CASELESS)
Если этот модификатор используется, символы в шаблоне соответствуют символам как верхнего, так и нижнего регистра.
- m (PCRE_MULTILINE)
По умолчанию PCRE обрабатывает данные как однострочную символьную строку
(даже если она содержит разделители строк).
Метасимвол начала строки '^' соответствует только началу обрабатываемого текста,
в то время как метасимвол "конец строки" '$' соответствует
концу текста, либо позиции перед завершающим текст переводом строки
(в случае, если модификатор D не установлен).
В Perl ситуация полностью аналогична.
Если этот модификатор используется, метасимволы "начало строки" и
"конец строки" также соответствуют позициям перед произвольным символом
перевода и строки и, соответственно, после.
Это соответствует Perl-модификатору \m.
В случае, если обрабатываемый текст не содержит символов перевода строки,
либо шаблон не содержит метасимволов '^' или '$',
данный модификатор не имеет никакого эффекта.
- s (PCRE_DOTALL)
Если данный модификатор используется, метасимвол "точка" в шаблоне соответствует
всем символам, включая перевод строк. Без него - всем, за исключением переводов строк.
Этот модификатор эквивалентен записи /s в Perl.
Класс символов, построенный на отрицании, например [^a], всегда соответствует
переводу строки, независимо от наличия этого модификатора.
- x (PCRE_EXTENDED)
Если данный модификатор используется, неэкранированные
пробелы, символы табуляции и пустой строки
в шаблоне игнорируются, если они не являются частью символьного класса.
Также игнорируются все символы между неэкранированным символом '#'
(если он не является частью символьного класса) и символом перевода строки
(включая сами символы '\n' и '#').
Это эквивалентно Perl-модификатору \x, и позволяет размещать комментарий
в сложных шаблонах.
Замечание: это касается только символьных данных. Пробельные символы
не фигурируют в служебных символьных последовательностях, к примеру, в
последовательности '(?(', открывающей условную подмаску.
- e
Если данный модификатор используется, preg_replace()
после выполнения стандартных подстановок в заменяемой строке
интерпретирует ее как PHP-код и использует результат для замены искомой строки.
Только preg_replace() реагирует на данный модификатор;
остальными функциями он игнорируется.
Замечание:
Этот модификатор недоступен в PHP 3.
- A (PCRE_ANCHORED)
Если данный модификатор используется, соответствие шаблону
будет достигаться только в том случае, если он
соответствует началу строки, в которой производится поиск.
Того же эффекта можно достичь подходящей конструкцией с вложенным
шаблоном, которая реализуема в Perl.
- D (PCRE_DOLLAR_ENDONLY)
Если данный модификатор используется, метасимвол $ в шаблоне
соответствует только окончанию обрабатываемых данных. Без этого модификатора
метасимвол $ соответствует также позиции перед последним символом, в случае,
если им является перевод строки (но не распространяется на любые другие переводы строк).
Данный модификатор игнорируется, если используется модификатор m.
В языке Perl аналогичный модификатор отсутствует.
- S
В случае, если планируется многократно использовать шаблон,
имеет смысл потратить немного больше времени на его анализ,
чтобы уменьшить время его выполнения.
В случае, если данный модификатор используется, проводится дополнительный анализ шаблона.
В настоящем это имеет смысл только для фиксированных шаблонов,
не содержащих переменных ссылок.
- U (PCRE_UNGREEDY)
Этот модификатор инвертирует жадность квантификаторов, таким
образом они по умолчанию не жадные. Но становятся жадными,
если за ними следует символ '?'. Такая возможность не совместима с Perl.
Модификатор U также может использоваться внутри шаблона,
при помощи '?U' записи.
- X (PCRE_EXTRA)
Этот модификатор включает дополнительную функциональность PCRE,
которая не совместима с Perl: любой обратный слеш в шаблоне, за которым следует
символ, не имеющий специального значения, приводят к ошибке.
Это обусловлено тем, что подобные комбинации зарезервированы для
дальнейшего развития. По умолчанию же, как и в Perl, слеш со следующим за ним
символом без специального значения трактуется как as опечатка.
На сегодняшний день это все возможности, которые управляются данным модификатором
- u (PCRE_UTF8)
Этот модификатор включает дополнительную функциональность PCRE,
которая не совместима с Perl: шаблоны обрабатываются как UTF8 строки.
Модификатор u доступен в PHP 4.1.0 и выше для Unix-платформ,
и в PHP 4.2.3 и выше для Windows платформ.
Модификаторы шаблонов
varrah NO_GARBAGE_OR_SPAM AT mail DOT ru
03-Nov-2005 04:12
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.
hfuecks at nospam dot org
15-Jul-2005 07:14
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";
}
}
?>
csaba at alum dot mit dot edu
08-Apr-2005 05:40
Extracting lines of text:
You might want to grab a line of text within a multiline piece of text. For example, suppose you want to replace the first and last lines within the <body> portion of a web $page with your own $lineFirst and $lineLast. Here's one possible way:
<?php
$lineFirst = "This is a new first line<br>\r\n";
$lineLast = "This is a new last line<br>\r\n";
$page = <<<EOD
<html><head>
<title>This is a test page</title>
</head><body>
This is the first line<br>
Hi Fred<br>
Hi Bill<br>
This is the last line<br>
</body>
</html>
EOD;
$re = "/<body>.*^(.+)(^.*?^)(.+)(^<\\/body>.*?)/smU";
if (preg_match($re, $page, $aMatch, PREG_OFFSET_CAPTURE))
$newPage = substr($text, 0, $aMatch[1][1]) .
$lineFirst . $aMatch[2][0] .
$lineLast . $aMatch[4][0];
print $newPage;
?>
The two (.+) are supposed to match the first and last lines within the <body> tag. The /s option (dot all) is needed so the .* can also match newlines. The /m option (multiline) is needed so that the ^ can match newlines. The /U option (ungreedy) is needed so that the .* and .+ will only gobble up the minimum number of characters necessary to get to the character following the * or +. The exception to this, however, is that the .*? temporarily overrides the /U setting on .* turning it from non greedy to greedy. In the middle, this ensures that all the lines except the first and last (within the <body> tag) are put into $aMatch[2]. At the end, it ensures that all the remaining characters in the string are gobbled up, which could also have been achieved by .*)\\z/ instead of .*?)/
Csaba Gabor from Vienna
| |