"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
A barra invertida tem vários usos. Primeiramente, se ela for seguida por um caractere não alfanumérico, ela remove qualquer significado especial que este caractere possa ter. Este uso da barra invertida como um caractere de escape se aplica tanto dentro quanto fora de classes de caracteres.
Por exemplo, se a intenção é casar com um caractere "*", deve-se escrever "\*" na expressão. Isto é aplicável mesmo que o próximo caractere pudesse ser interpretado como um metacaractere, por isso é sempre seguro preceder um caractere não alfanumérico com "\" para especificar que ele irá representar a si mesmo. Em particular, se a intenção for casar com uma barra invertida, deve-se escrever "\\".
Nota:
strings do PHP com aspas simples e aspas duplas têm significado especial para a barra invertida. Assim, se \ precisa corresponder a uma expressão regular \\, então "\\\\" ou '\\\\' precisam ser usadas no código PHP.
Se uma expressão for compilada com a opção PCRE_EXTENDED, espaços em branco na expressão (que não estejam em uma classe de caracteres) e caracteres entre um "#" fora de uma classe de caracteres e o próximo caractere de nova linha são ignorados. Uma barra invertida de escape pode ser usada para incluir um espaço ou um caractere "#" como parte da expressão.
Um segundo uso da barra invertida fornece um meio de codificar caracteres não imprimíveis de uma maneira visível. Não há restrição para presença de caracteres não imprimíveis, exceto pelo zero binário que termina uma expressão, mas quando uma expressão está sendo preparada durante a edição de texto, normalmente é mais fácil usar uma das sequências de escape a seguir do que usar o caractere binário que ela representa:
O efeito preciso de "\cx
" é o seguinte:
se "x
" for uma letra minúscula, ela é convertida
para maiúscula. Depois, o bit 6 do caractere (hexa 40) é invertido.
Portanto, "\cz
" se torna hexa 1A, mas
"\c{
" se torna hexa 3B, enquanto que "\c;
"
se torna hexa 7B.
Depois de "\x
", até dois dígitos hexadecimais são
lidos (letras podem ser minúsculas ou maiúsculas).
No modo UTF-8, "\x{...}
" é
permitido, onde o conteúdo entre chaves é uma string de dígitos
hexadecimais. É interpretado como um caractere UTF-8 cujo número de código é
o número hexadecimal informado. A sequência de escape hexadecimal original,
\xhh
, corresponde a um caractere UTF-8 de dois bytes se o valor
for maior que 127.
Depois de "\0
" até dois dígitos octais adicionais são lidos.
Em ambos os casos, se eles forem menos que dois, apenas os presentes
são usados. Assim, a sequência "\0\x\07
"
especifica dois zeros binários seguidos por um caractere BEL. Certifique-se de
fornecer dois dígitos depois do zero inicial se o caractere
seguinte for, por acaso, um dígito octal.
A interpretação de uma barra invertida seguida por um dígito que não seja 0 é complicada. Fora de uma classe de caracteres, o PCRE lê este dígito e os seguintes como um número decimal. Se o número for menor que 10, ou se houve pelo menos esta quantidade de grupos em parênteses na expressão, a sequência inteira é interpretada como uma referência retroativa. Uma descrição de como isto funciona é fornecida mais abaixo, logo após a discussão sobre sub-expressões entre parênteses.
Dentro de uma classe de caracteres, ou se o número decimal for maior que 9 e não houve essa quantidade de sub-expressões de captura, o PCRE lê novamente até três dígitos octais depois da barra invertida, e gera um único byte a partir dos 8 bits menos significativos do valor. Quaisquer dígitos subsequentes representam a si mesmos. Por exemplo:
Observe que valores octais de 100 ou maiores não podem ser introduzidos com um zero na frente, porque não mais que três dígitos octais são lidos no total.
Todas as sequências que definem um valor de byte único podem ser
usadas tanto dentro quanto fora de classes de caracteres. Além disso,
dentro de uma classe de caracteres, a sequência "\b
"
é interpretada como o caractere "backspace" (hexa 08). Fora de uma classe de
caracteres ela tem um significado diferente (veja abaixo).
O terceiro uso da barra invertida é para especificar tipos genéricos de caracteres:
Cada par de sequência de escape particiona o conjunto completo de caracteres em dois conjuntos desconexos. Cada caractere informado corresponde a um, e apenas um, de cada par.
Os caracteres que representam um espaço em branco horizontal são tabulação horizontal (9), nova linha (10), alimentação de formulário (12), retorno de carro (13), e espaço (32). No entanto, em casos de correspondências específicas de localidade, caracteres com pontos de código na faixa de 128 a 255 podem também ser considerados como caracteres de espaço em branco, por exemplo, NBSP (A0).
Uma caractere de uma "palavra" é qualquer letra ou dígito ou o caractere
de sublinhado "_", isto é, qualquer caractere que possa fazer parte de uma
"palavra" em Perl. A definição de letras e dígitos é
controlada pelas tabelas de caracteres do PCRE, e pode varia se correspondências específicas
de localidade estiverem ocorrendo. Por exemplo, na localidade "pt-BR" (português do Brasil), alguns
códigos de caracteres maiores que 127 são usados para letras acentuadas,
e estes são correspondidos por \w
.
Estas sequências de tipo de caracteres podem aparecer tanto dentro como fora de classes de caracteres. Cada uma corresponde a um caracteres do tipo apropriado. Se o ponto de correspondência atual estiver no final da string de entrada, todos eles irão falhar, já que não haverá caractere para correspondência.
O quarto uso da barra invertida é para certas afirmações simples. Uma afirmação especifica uma condição que deve ser encontrada em um ponto particular de uma correspondência, sem consumir nenhum caractere da string de entrada. O uso de sub-expressões para afirmações mais complicadas é descrito abaixo. As afirmaçõs que usam barra invertida são:
Estas afirmações podem não aparecer em classes de caracteres (mas
observe que "\b
" tem um significado diferente, que é o caractere
de "backspace" dentro de uma classe de caracteres).
Uma borda de palavra é uma posição na string de entrada onde
nem o caractere atual nem o caractere anterior
correspondem a \w
ou \W
ao mesmo tempo (isto é, um deles corresponde a
\w
e o outro corresponde a
\W
), ou o início ou final da string se o primeiro
ou último caractere corresponder a \w
, respectivamente.
As afirmações \A
, \Z
e
\z
diferem dos tradicionais
circunflexo "^" e cifrão "$" (descritos em âncoras )
porque elas somente são correspondidas exatamente no início e no final da string de entrada,
não importa que opções estão definidas. Elas não são afetada pelas opções
PCRE_MULTILINE ou
PCRE_DOLLAR_ENDONLY.
A diferença entre \Z
e
\z
é que \Z
corresponde antes de um caractere de
nova linha que é o último caractere da string e também no final da
string, enquanto que \z
corresponde apenas no final.
A afirmação \G
é verdadeira somente quando a posição
de correspondência atual é no ponto inicial da corresponência, como especificado pelo
argumento offset
da função
preg_match(). Ela difere de \A
quando o valor de offset
é não-zero.
\Q
e \E
podem ser usadas para ignorar
metacaracteres na expressão. Por exemplo:
\w+\Q.$.\E$
irão corresponder a um ou mais caracteres de palavras,
seguidos pelos literais .$.
e ancorados no final da
string. Observe que isto não muda o comportamento dos
delimitadores; por exemplo, a expressão #\Q#\E#$
não é válida, porque o segundo #
marca o final
da expressão, e o \E#
é interpretado como modificador
inválido.
\K
pode ser usado para redefinir o início da correspondência.
Por exemplo, a expressão foo\Kbar
corresponde a
"foobar", mas reporta que correspondeu a "bar". O uso de
\K
não interfere com a configuração de substrings
capturadas. Por exemplo, quando a expressão (foo)\Kbar
corresponde a "foobar", a primeira substring ainda será definida como "foo".
"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.