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

Mah*_*han 29 php regex

出于好奇,我试图弄清楚哪种正确的方法来逃避反斜杠用于PHP正则表达式模式,如下所示:

测试01:(3个反斜杠)

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

// ----- RETURNS A MATCH -----
Run Code Online (Sandbox Code Playgroud)

测试02:(4个反斜杠)

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

// ----- ALSO RETURNS A MATCH -----
Run Code Online (Sandbox Code Playgroud)

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

资源:

Mik*_*keM 43

// 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
Run Code Online (Sandbox Code Playgroud)

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

echo preg_match( '/\\\\s/', '\\ ' );    // 0  
echo preg_match( '/\\\\s/', '\\s' );    // 1  
Run Code Online (Sandbox Code Playgroud)

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

echo preg_match( '/\\\\\s/', '\\ ' );   // 1
echo preg_match( '/\\\\\s/', '\\s' );   // 0
Run Code Online (Sandbox Code Playgroud)

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

echo preg_match( '/[\\\\s]/', ' ' );   // 0 
echo preg_match( '/[\\\\\s]/', ' ' );  // 1 
Run Code Online (Sandbox Code Playgroud)

将字符串括在double而不是单引号中会影响上述结果.

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

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

逃脱序列.


Оле*_*ьев 11

为了避免这种不清楚的代码你可以使用\ x5c 像这样:)

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


Mar*_*c B 5

问题是,您使用的是字符类, [],因此无论嵌入多少文字反斜杠都无关紧要,它将被视为单个反斜杠。

例如以下两个正则表达式:

/[a]/
/[aa]/
Run Code Online (Sandbox Code Playgroud)

就正则表达式引擎而言,所有意图和目的都是相同的。字符类采用字符列表并将它们“折叠”以匹配单个字符,沿着“对于当前正在考虑的字符,它是[]? 中列出的任何字符”。如果您在类中列出两个反斜杠,那么它将是“字符是黑斜杠还是反斜杠?”。

  • `\[\]` 将是结束括号的转义符。`[\\]` 将是字符类中的反斜杠。单个字符类是毫无意义的,它与只有一个裸露的 `\\\` 没有什么不同。 (3认同)

Ada*_*dam 5

答案/sf/answers/1075887991/非常说明性,但如果你不知道PHP字符串中反斜杠的核心问题,你根本不会理解它。

PHP 字符串中反斜杠的核心问题在https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.single进行了解释,您可能需要注意最后两句:

指定字符串的最简单方法是将其括在单引号(字符 ')中。

要指定文字单引号,请使用反斜杠 () 将其转义。要指定文字反斜杠,请将其加倍 (\)。所有其他反斜杠实例将被视为文字反斜杠

简而言之,字符串中的两个反斜杠代表文字反斜杠。后面不跟 a 的单个反斜杠'也表示字面反斜杠。

这有点奇怪,但它意味着一个字符串'\\xxx',并且'\xxx'都代表相同的字符串\xxx
请注意,这'\\'xxx'是一个无效字符串,而'\'xxx'表示字符串'xxx

我猜它源于此:如果你想要一个字面上的单引号,你需要用反斜杠转义它。所以'hi\''代表字符串hi'。但现在你最终会遇到这样的情况:你可能想要创建字符串hi\'hi\'不再起作用(像这样的无效字符串没有结束')。因此,需要一个额外的转义来防止 中 的特殊含义\。因此,我们决定\转义\hi\可以写成 'hi\\'

这就是为什么 与(都代表\\'\\\' )相同的原因,并且对于这两个字符串,您使用什么并不重要。'\\\\'

然而,它有一个令人惊讶的效果,如果你将字符串加倍,它们就不一样了。这是因为用单引号括起来的 3 个反斜杠代表 2 个文字反斜杠。但是用单引号括起来的 6 个反斜杠仅代表 3 个文字反斜杠。而用单引号括起来的 4 个反斜杠代表 2 个文字反斜杠,用单引号括起来的 8 个反斜杠代表 4 个文字(请参阅 MikeM 的示例)。因此,建议始终使用 4 而不是 3。