在PHP正则表达式中转义反斜杠[\]的正确方法?

在PHP正则表达式中转义反斜杠[\]的正确方法?,php,regex,Php,Regex,出于好奇,我试图找出在PHP正则表达式模式中使用反斜杠的正确方法,如下所示: 测试01:(3次反斜杠) 测试02:(4个反斜杠) 根据下面的文章,4应该是正确的方法,但让我困惑的是,两个测试都返回了一个匹配。如果两者都正确,那么4是首选方式吗 资源: 问题是,您正在使用一个字符类,[],因此无论其中嵌入了多少个文字反斜杠,它都将被视为一个反斜杠 e、 g.以下两个正则表达式: /[a]/ /[aa]/ 就正则表达式引擎而言,所有意图和目的都是相同的。字符类获取字符列表并“折叠”它们以匹配

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

测试01:(3次反斜杠)

测试02:(4个反斜杠)

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

资源:


问题是,您正在使用一个字符类,
[]
,因此无论其中嵌入了多少个文字反斜杠,它都将被视为一个反斜杠

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

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

当使用三个反斜杠匹配
'\'
时,下面的模式被解释为匹配
'\'
,后跟
'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 
将字符串用双引号而不是单引号括起来不会影响上述结果

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

推荐:
当试图匹配反斜杠时,在正则表达式模式中始终使用四个反斜杠


.

我这几年前就开始学习了。这是因为第一个反斜杠转义了第二个反斜杠,它们一起在模式中形成了一个“真斜杠”字符,而这个真斜杠转义了第三个字符。因此,它神奇地使3个反斜杠工作

然而,通常的建议是使用4个反斜杠,而不是模糊的3个反斜杠


如果我有任何错误,请随时纠正。

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

echo preg\u replace('/\x5c\w+\.php$/i'、'${0}'、\uuu文件\uuuu);

您还可以使用以下命令

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

$regexp=因此在这两种情况下,regex引擎都将其视为一个反斜杠?
\[\]
将是结束括号的转义<代码>[\\]
将是字符类中的反斜杠。一个单独的char类是毫无意义的,它与只有一个空的`\\``没有什么区别。当我尝试[\]时,我总是得到消息:preg\u match():编译失败:缺少终止]对于偏移量3-1处的character类:
,而这个真实的类会转义第三个
否。只执行一次传递。第三个反斜杠“转义”了
]
(这只会自动生成
]
。@Lightness:那么为什么“/(\\\r)\1+/”会匹配重复的“\”和“r”(我的意思是两个真字符)?你能解释一下吗?
\r
是一个转义序列<代码>\]不是。我只想说一声非常感谢。转义转义字符(如
\n
已经很痛苦了,但在带有lookbehind的正则表达式中转义是一项挑战。避免使用
反斜杠
只会再次替换为另外三个字符和反斜杠。呸!
echo preg_match( '/\\\\\s/', '\\ ' );   // 1
echo preg_match( '/\\\\\s/', '\\s' );   // 0
echo preg_match( '/[\\\\s]/', ' ' );   // 0 
echo preg_match( '/[\\\\\s]/', ' ' );  // 1 
echo preg_replace( '/\x5c\w+\.php$/i', '<b>${0}</b>', __FILE__ );
$regexp = <<<EOR
schemaLocation\s*=\s*["'](.*?)["']
EOR;
preg_match_all("/".$regexp."/", $xml, $matches);
print_r($matches);