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.
Modificadores de Patrón
(No version information available, might only be in CVS)
Modificadores de Patrón — Describe los posibles modificadores en patrones de expresiones regulares
Descripción
Los modificadores PCRE disponibles en la actualidad son listados a continuación. Los nombres entre paréntesis se refieren a nombres internos de PCRE para dichos modificadores. Los espacios y saltos de línea son ignorados en los modificadores, otros caracteres generan error.
- i (PCRE_CASELESS)
- Si este modificador es definido, las letras en el patrón coincidirán tanto con letras mayúsculas como minúsculas.
- m (PCRE_MULTILINE)
- Por omisión, PCRE trata la cadena de asunto como si consistiera de una "única" línea de caracteres (aun si en realidad contiene varias). El meta-caracter de "inicio de línea" (^) coincide sólo al principio de la cadena, mientras que el meta-caracter de "fin de línea" ($) coincide sólo el final de la cadena, o antes un caracter de nueva línea final (a menos que el modificador D sea definido). Esto es igual que en Perl. Cuando este modificador es definido, los constructores de "inicio de línea" y "fin de línea" coinciden inmediatamente después o inmediatamente antes de cualquier caracter de nueva línea, respectivamente, al igual que al comienzo o final absoluto de la cadena. Este comportamiento es equivalente al modificador /m del Perl. Si no hay caracteres "\n" en la cadena de asunto, o no hay ocurrencias de ^ o $ en un patrón, este modificador no tiene efecto alguno.
- s (PCRE_DOTALL)
- Si se define este modificador, un meta-caracter de punto en el patrón coincidirá con todos los caracteres, incluyendo el de nueva línea. Sin él, los saltos de línea son excluídos. Este modificador es equivalente a /s en Perl. Una clase negativa como [^a] siempre coincide con un caracter de nueva línea, independientemente del uso de este modificador.
- x (PCRE_EXTENDED)
- Si este modificador es definido, los caracteres de datos que representan espacios en blanco en el patrón son completamente ignorados, excepto cuando son escapados o cuando se encuentran al interior de una clase caracter, y los caracteres entre un # sin escapar fuera de una clase de caracter y el siguiente caracter de nueva línea, inclusive, son ignorados también. Esto es equivalente al modificador /x de Perl y hace posible incluir comentarios al interior de patrones complicados. Note, sin embargo, que esto es sólo aplicable a caracteres de datos. Los caracteres de espacio en blanco nunca pueden aparecer en secuencias de caracteres especiales en un patrón, por ejemplo al interior de la secuencia (?(, la cual inicia un sub-patrón condicional.
- e (PREG_REPLACE_EVAL)
- Si este modificador es usado, preg_replace() realiza las sustituciones normales de referencias hacia atrás en la cadena de reemplazo, evalúa ésta como código PHP y usa el resultado para reemplazar la cadena de búsqueda. Las comillas sencillas, comillas dobles, barras invertidas y caracteres NULL serán escapados con barras invertidas en las referencias hacia atrás sustituidas.
Sólo preg_replace() usa este modificador; es ignorado por otras funciones de PCRE.
Note: Este modificador no se encontraba disponible en PHP 3.
- A (PCRE_ANCHORED)
- Si este modificador es definido, el patrón es obligado a ser "anclado", es decir, es limitado para que coincida sólo al inicio de la cadena que está siendo analizada (la "cadena de asunto"). Este efecto puede alcanzarse también mediante las construcciones apropiadas en el patrón mismo, la cual es la única manera de hacerlo en Perl.
- D (PCRE_DOLLAR_ENDONLY)
- Si este modificador es definido, un meta-caracter de signo dólar en el patrón coincide únicamente al final de la cadena de asunto. Sin este modificador, un dólar coincide también inmediatamente antes del caracter final si éste es un salto de línea (pero no antes de cualquier otra nueva línea). Este modificador es ignorado si m es definido. No hay equivalente en Perl para este modificador.
- S
- Cuando un patrón va a ser usado varias veces, vale la pena dedicar más tiempo a analizarlo para acelerar el proceso de comparaciones. Si este modificador es definido, entonces se realizará este análisis adicional. Por el momento, el estudio de un patrón es útil sólo para patrones no-anclados que no tienen un carácter de inicio único arreglado.
- U (PCRE_UNGREEDY)
- Este modificador invierte la "ambición" de los cuantificadores, de modo que no sean codiciosos por defecto, en su lugar se vuelven codiciosos si son seguidos por un "?". No es compatible con Perl. También puede definirse con un modificador (?U) al interior del patrón o con un signo de interrogación antes del cuantificador (p.ej. .*?).
- X (PCRE_EXTRA)
- Este modificador activa funcionalidad adicional de PCRE que no es compatible con Perl. Cualquier barra invertida en un patrón que sea seguida por una letra que no tenga un significado especial provocará un error, logrando en efecto reservar estas combinaciones para futuras ampliaciones. Por defecto, como en Perl, una barra invertida seguida por una letra sin un significado especial es tratada como un literal. No hay otras características controladas por este modificador a la fecha de hoy.
- u (PCRE_UTF8)
- Este modificador activa funcionalidad adicional de PCRE que no es compatible con Perl. Las cadenas de patrones son tratadas como UTF-8. Este modificador se encuentra disponible a partir de PHP 4.1.0 o versiones posteriores en Unix, y desde PHP 4.2.3 en win32. La validez UTF-8 del patrón es verificada desde PHP 4.3.5.
Modificadores de Patrón
michal dot kocarek at brainbox dot cz
18-May-2009 11:49
18-May-2009 11:49
ebarnard at marathonmultimedia dot com
06-Feb-2007 10:35
06-Feb-2007 10:35
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
varrah NO_GARBAGE_OR_SPAM AT mail DOT ru
03-Nov-2005 12:12
03-Nov-2005 12: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 02:14
15-Jul-2005 02: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
09-Apr-2005 12:40
09-Apr-2005 12: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
