我有这个字符串:
$var = "Foo (.* ) bar blla (.* ) b*l?a$ bla bla ";
我想逃避*和?以及未收集到此形状的所有特殊字符
"&#34(*);
我想使用preg_quote($var, '\')
但它逃脱了所有特殊字符,我只需要转义单个特殊字符。
我想要这个结果:
$var = "Foo (.* ) bar bla(.*) b\*l\?a\$ bla bla ";
我想在preg_match中使用最终的$ var(结果),匹配另一个字符串中的所有(。*),以及我的案例中的特殊字符:
。,\,^,$,|,?,*,+,(,),[,],{,}和/
应该被解析为普通文本,因此应该对它们进行转义。虽然(。*)一个不应该被逃脱。 只有上面的特殊字符才能被转义,因为我必须在preg_match中使用$ var。其他特殊字符,无需逃避它们。
preg_match("/" . $var . "/s", $anotherstring, $match);
答案 0 :(得分:2)
<强> EDIT3 强>
好像它不适合你,所以这是另一次尝试。由于mickmack似乎对性能感到担心,他会很高兴它会下降到146步;)
替换
([\w\s]*(?:\([^)]*\)[\w\s]*)*)([*?$&])
与
$1\\$2
它捕获可选范围的非特殊字符。它继续捕获可选的带括号的组,后跟可选的非特殊字符范围。最后一部分可以重复任意次。最后它捕获了特殊的角色。
所以我们必须捕获组 - 一组带有导致特殊字符的文本(如果有的话),另一组带有特殊字符。
用中间的\
取代它们的内容,就可以了。
括号部分(happy mick ?;)也更灵活。它允许括号内更复杂的正则表达式(只是没有嵌套的括号)。
如果处理\
的新要求不是必须的,而否定的单词类就行\W
,我们就会陷入炽热的76步 :) Here at regex101。
- 原始回答 -
这是一种方法 - 替换
(?<!\(|\(.|\(..)([^\w\s])(?![^(]*\))
与
\$1
注意!你必须逃脱php字符串中的\
- 即“\\ $ 1”。
由于php只允许使用look-behinds进行修复,因此它使用(?<!\(|\(.|\(..|\(...)
构造在四个步骤中测试特殊字符之前没有开括号。然后它匹配并捕获特殊字符(不是字符,也不是空格)。最后,它使用负向前瞻以确保它后面没有右括号。在和之前检查括号可能是多余的。
替换匹配的,捕获的角色本身 - $1
- 前面有想要的转义字符\
就可以了。
修改强>
如果特殊字符仅限于您示例中的特殊字符,请使用
(?<!\(\.)([*?$&])(?!\))
作为搜索字符串并替换为\$1
。
匹配您的特殊字符,只要它们前面没有(.
,后面跟)
。
(这两种方式都没有防水,因为它们无法逃离 &
中的(.& )
。)
<强> EDIT2 强>
由于OP将有问题的转义字符从/
更改为\
,因此已更新。
并删除了捕获组内的空间,因为OP不需要它。
答案 1 :(得分:1)
以下几种模式的表现优于ClasG的答案:
输入:Foo (.* ) bar blla (.* ) b*l?a$ && bla bla
模式:/\([^)]*\)(*SKIP)(*FAIL)|([^a-z\d ])/i
替换为:\\\1
输出:Foo (.* ) bar blla (.* ) b\*l\?a\$ \&\& bla bla
Pattern Demo(仅 122 步骤)
基本上它只是省略了#34;受保护的&#34;括号部分并匹配任何非alphebetic&amp; amp;非空格字符。
如果你想专门列出这些符号,你可以将这个否定的字符类更改为OP中的字符类,如下所示:(仍 122 步骤)
/\([^)]*\)(*SKIP)(*FAIL)|([-\/~`!@#$%^&*()_+={}[\]|;:'"<>,.?\\])/
或者您只能使用示例中的符号,此处为完整模式(仍然 122 步骤):
/\([^)]*\)(*SKIP)(*FAIL)|([*?$&])/
所有ClasG的模式都比我上面的3种模式慢:
ClasG的书面模式:
(?<!\(|\(.|\(..)([^\w\s])(?![^(]*\))
失败 并采取 418 步骤 - demoClasG的链接演示模式:
(?<!\(|\(.|\(..)([^\w\s])(?![^(]*\))
是 正确但需要 367 步骤 - demoClasG的第三种模式:
(?<!\(\.)([*?$&])(?!\))
是正确的,但有一个 对括号部分的严格要求。这是最好的 该答案中的模式采取 186 步骤 - demo。
答案 2 :(得分:-1)
使用preg_replace_callback,您可以查看正则表达式https://regex101.com/r/52qQwv/1
$s = 'Foo (.*) bar blla (.*) b*l?a$&& bla bla';
$regexp = '/([\.\*\?\&\$])[\w\s\&]/iu';
$f = function ($matches) {
return '/' . $matches[1];
};
$a = preg_replace_callback($regexp, $f, $s);
var_dump($a);
string(39)“Foo(。)bar blla(。)b / * /?/ $ /&amp; bla bla”