正确的方法来逃避PHP正则表达式中的反斜杠[\]?

时间:2012-06-15 03:13:23

标签: php regex

出于好奇,我正在试图找出哪种正确的方法来逃避反斜杠,以便在PHP正则表达式模式中使用,如下所示:

测试01 :( 3个反斜杠)

$pattern = "/^[\\\]{1,}$/";
$string = '\\';

// ----- RETURNS A MATCH -----

测试02 :( 4个反斜杠)

$pattern = "/^[\\\\]{1,}$/";
$string = '\\';

// ----- ALSO RETURNS A MATCH -----

根据下面的文章,4应该是正确的方法,但令我困惑的是两个测试都返回了匹配。如果两者都是正确的,那么4是首选方式吗?

资源:

5 个答案:

答案 0 :(得分:41)

// PHP 5.4.1

// Either three or four \ can be used to match a '\'.
echo preg_match( '/\\\/', '\\' );        // 1
echo preg_match( '/\\\\/', '\\' );       // 1

// Match two backslashes `\\`.
echo preg_match( '/\\\\\\/', '\\\\' );   // Warning: No ending delimiter '/' found
echo preg_match( '/\\\\\\\/', '\\\\' );  // 1
echo preg_match( '/\\\\\\\\/', '\\\\' ); // 1

// Match one backslash using a character class.
echo preg_match( '/[\\]/', '\\' );       // 0
echo preg_match( '/[\\\]/', '\\' );      // 1  
echo preg_match( '/[\\\\]/', '\\' );     // 1

当使用三个反斜杠匹配'\'时,下面的模式被解释为匹配'\'后跟's'

echo preg_match( '/\\\\s/', '\\ ' );    // 0  
echo preg_match( '/\\\\s/', '\\s' );    // 1  

当使用四个反斜杠匹配'\'时,下面的模式被解释为匹配'\'后跟空格字符。

echo preg_match( '/\\\\\s/', '\\ ' );   // 1
echo preg_match( '/\\\\\s/', '\\s' );   // 0

如果在字符类中,则同样适用。

echo preg_match( '/[\\\\s]/', ' ' );   // 0 
echo preg_match( '/[\\\\\s]/', ' ' );  // 1 

上述结果都不会受到以双引号而不是单引号括起来的影响。

<强>结论:
无论是在括号内的字符类的内部还是外部,只需使用三个反斜杠'\\\'即可匹配文字反斜杠,除非模式中的下一个字符也被反斜杠,在这种情况下,必须使用四个反斜杠匹配文字反斜杠。

<强>建议:
在寻求匹配反斜杠时,始终在正则表达式模式中使用四个反斜杠'\\\\'

Escape sequences

答案 1 :(得分:11)

要避免使用此类不清楚的代码,您可以使用 \ x5c 像这样:)

echo preg_replace( '/\x5c\w+\.php$/i', '<b>${0}</b>', __FILE__ );

答案 2 :(得分:4)

问题是,你正在使用一个字符类[],因此嵌入多少字面反斜杠并不重要,它将被视为一个反斜杠。

e.g。以下两个正则表达式:

/[a]/
/[aa]/
就正则表达式引擎而言,

用于所有意图和目的相同。字符类采用字符列表并将其“折叠”以匹配单个字符,沿着“对于当前正在考虑的字符,是[]中列出的任何字符?”的行。如果在类中列出两个反斜杠,那么它将是“char是一个黑色斜杠还是反斜杠?”。

答案 3 :(得分:1)

我多年前就研究过了。这是因为第一个反斜杠逃脱了第二个,它们在一起形成了一个'真正的baclkslash'字符,这个真正的反转是第三个。所以它神奇地使3个反斜杠工作。

但是,正常的建议是使用4个反斜杠而不是模糊的3个反斜杠。

如果我对任何事情都不对,请随时纠正我。

答案 4 :(得分:0)

您还可以使用以下

$regexp = <<<EOR
schemaLocation\s*=\s*["'](.*?)["']
EOR;
preg_match_all("/".$regexp."/", $xml, $matches);
print_r($matches);

关键字:dochere,nowdoc