使用正则表达式获取和替换带引号的字符串

时间:2012-09-28 20:27:41

标签: php regex

我正在尝试在引用中获取字符串。 我正在使用正则表达式,但我有转义引号的问题。

例如,我有这个:

$var = "SELECT * FROM TABLE WHERE USERNAME='Carasuman'";
preg_match_all('~([\'"])(.*?)\1~s', $var, $result);
$new = preg_replace('~([\'"])(.*?)\1~s',"<#################>",$var);

代码完美无缺。我在$ new [1]

中获得$ new和引用值的替换值
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>";
$result[1] = "Carasuman";

我的问题是当我在引号中添加一个scaped引用时:

$var = "SELECT * FROM TABLE WHERE USERNAME='Carasuman\'s'";

我明白了:

$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>'s";
$result[1] = "Carasuman\" //must be "Carasuman\'s";

如何避免此错误并获得$ new和$ result [1],就像第一个例子一样?:

$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>";
$result[1] = "Carasuman\'s";

谢谢!

3 个答案:

答案 0 :(得分:1)

对于比赛,你永远不会得到 Carasuman's 而没有\作为单个匹配元素,因为你可以在一场比赛中匹配跳过chars。它要么抓住 Carasuman ,要么 Carasuman的
只需使用str_replace来摆脱反斜杠

preg_match_all('~([\'"])(.*)\1~s', $var, $result);
$result[2] = str_replace('\\','',$result[2]);

替换,?在(。*?)组中使它不合适,这意味着它将在第一场比赛时停止。除掉 ?在(。*?)中使它变得贪婪,这意味着它会一直持续到最后一场比赛

preg_replace('~([\'"])(.*)\1~s',"<#################>",$var);

修改

而不是在$ result [2]上匹配后执行str_replace,最好先在初始字符串上执行,如:

$var = str_replace("\\'","'",$var); 
preg_match_all('~([\'"])(.*)\1~s', $var, $result);
$new = preg_replace('~([\'"])(.*)\1~s',"<#################>",$var);

你仍然需要使你的通配符匹配像(。*?)一样贪婪(。*),以便在匹配/替换中包含名称中的撇号而不是被计为终止单引号

答案 1 :(得分:0)

你为什么不这样做:

$var = "SELECT * FROM TABLE WHERE USERNAME='" . mysql_real_escape_string($input) . "'";

我认为你不一定需要做正则表达式。此外,mysql_real_escape_string正确地转义了您的输入,因此您可以$input = 'Carasuman\'s';$input = "Carasuman's";

答案 2 :(得分:0)

要匹配引用的字符串,您可以使用正则表达式'\'.*?(?:\\\\.[^\\\\\']*)*\''和四个双引号字符串'".*?(?:\\\\.[^\\\\"]*)*"'