如何在一个正则表达式中不匹配

时间:2014-05-07 00:48:50

标签: php regex match pcre

我尝试使用preg_match验证查询。我想替换所有%s,%d和%f,但不能替换为\%s,\%d和\%f。我的正则表达是:

$query = "UPDATE FROM lol SET lol = \%s, asd = %s WHERE lol = %d";
$reg = preg_match("(\%s|\%d|\%f)(?!\\\%s|\\\%d|\\\%f)", $query, $matches);
var_dump($matches); // %s and %d, because \%s can't be matched

我试图与\%s不匹配,因为如果您执行以下操作:" WHERE st LIKE%s" (从s开始)它会崩溃。然后我想用正则表达式验证它并在替换后删除斜杠。我将使用匹配%s,%d和%f来替换它,如str,int和float,所以我想只使用一个正则表达式。你能救我吗?

2 个答案:

答案 0 :(得分:2)

(?<!\\)(%s|%d|%f)

没有测试PHP tho ...因为PHP中的正则表达式是字符串,所以你需要另外转义两个反斜杠中的每一个,所以你的PHP字符串中应该有四个。您需要考虑两个级别的转义,PHP字符串和正则表达式。

编辑:测试:

echo preg_replace("/(?<!\\\\)(%s|%d|%f)/", "replaced", "%s \\%s X%d")."\n";
// => replaced \%s Xreplaced

您的代码查找%s,%d,%f 后面没有%s,%d或%f (没有反斜杠,因为字符串转义剥离一个,留下\%s等,就regexp而言,这相当于%s,因为%不需要转义)。我的代码查找%s,%d,%f ,前面没有\

EDIT2:对于你的情况,

$query = "UPDATE FROM lol SET lol = \%s, asd = %s WHERE lol = %d";
$reg = preg_replace_callback("/(?<!\\\\)(%s|%d|%f)/", function($m) {
    $repl = Array("%d" => "int", "%s" => "str", "%f" => "float");
    return $repl[$m[1]];
  }, $query);
echo $reg."\n";
// => UPDATE FROM lol SET lol = \%s, asd = str WHERE lol = int

然而,看看你正在做什么,你可能更明智地使用ADODB或类似的东西来绑定参数,而不是自制解决方案。

答案 1 :(得分:1)

Zerquix,这是我能想到的最紧凑的正则表达式。它只与正确的匹配。

$regex = "~\\\\%(*SKIP)(*F)|%[sdf]~";
$string = "match %s, %d and %f but NOT with \%s, \%d and \%f.";
if(preg_match_all($regex,$string,$m)) print_r($m);

请参阅live demo