preg_replace中替换数组中的特殊(转义)字符会被转义

时间:2011-03-05 22:47:46

标签: php escaping preg-replace special-characters

我正在尝试修改以下表单的字符串,其中每个字段由制表符分隔,但第一个字符串后面跟着两个或多个制表符。

"$str1      $str2   $str3   $str4   $str5   $str6"

修改后的字符串将每个字段都包装在HTML表格标签中,并且自己的缩进行也是如此。

"<tr>
  <td class="title">$str1</td>
  <td sorttable_customkey="$str2"></td>
  <td sorttable_customkey="$str3"></td>
  <td sorttable_customkey="$str4"></td>
  <td sorttable_customkey="$str5"></td>
  <td sorttable_customkey="$str6"></td>
</tr>

"

我尝试使用以下代码来执行此操作。

$patterns = array();
$patterns[0]='/^/';
$patterns[1]='/\t\t+/';
$patterns[2]='/\t/';
$patterns[3]='/$/';

$replacements = array();
$replacements[0]='\t\t<tr>\r\n\t\t\t<td class="title">';
$replacements[1]='</td>\r\n\t\t\t<td sorttable_customkey="';
$replacements[2]='"></td>\r\n\t\t\t<td sorttable_customkey="';
$replacements[3]='"></td>\r\n\t\t</tr>\r\n';

for ($i=0; $i<count($lines); $i++) {
  $lines[$i] = preg_replace($patterns, $replacements, $lines[$i]);
}

问题是替换数组中的转义字符(制表符和换行符)在目标字符串中保持转义,我得到以下字符串。

"\t\t<tr>\r\n\t\t\t<td class="title">$str</td>\r\n\t\t\t<td sorttable_customkey="$str2"></td>\r\n\t\t\t<td sorttable_customkey="$str3"></td>\r\n\t\t\t<td sorttable_customkey="$str4"></td>\r\n\t\t\t<td sorttable_customkey="$str5"></td>\r\n\t\t\t<td sorttable_customkey="$str6"></td>\r\n\t\t</tr>\r\n"

奇怪的是,我之前在上尝试的这条线确实工作:

$data=preg_replace("/\t+/", "\t", $data);

我错过了什么吗?知道怎么解决吗?

2 个答案:

答案 0 :(得分:1)

替换字符串需要双引号或heredocs - PCRE仅解析搜索字符串中的转义字符。

在您的工作示例preg_replace("/\t+/", "\t", $data)中,这些都是文字制表符,因为它们是双引号。

如果您将其更改为preg_replace('/\t+/', '\t', $data),则可以观察到您的主要问题 - PCRE了解搜索字符串中的\t表示标签,但不替换替换字符串中的标签。< / p>

因此,通过使用双引号进行替换,例如preg_replace('/\t+/', "\t", $data),您让PHP解析\t并获得预期结果。

这有点不协调,只是要记住的东西。

答案 1 :(得分:1)

您的$replacements数组的所有字符串都被称为单引号字符串。 这意味着转义的字符不会花费(\'除外)。

它与PCRE正则表达式没有直接关系,而是与PHP如何处理字符串有关。

基本上你可以输入这样的字符串:

<?php # String test

$value = "substitution";
$str1 = 'this is a $value that does not get substituted';
$str2 = "this is a $value that does not remember the variable"; # this is a substitution that does not remember the variable
$str3 = "you can also type \$value = $value" # you can also type $value = substitution
$bigstr =<<< MARKER
you can type
very long stuff here
provided you end it with the single
value MARKER you had put earlier in the beginning of a line
just like this:
MARKER;

tl; dr版本:问题是$replacements$patterns中的单引号应该是双引号