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

发布于 2024-10-20 08:57:29 字数 1706 浏览 8 评论 0原文

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

"$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);

我错过了什么吗?知道如何修复它吗?

I’m trying to modify a string of the following form where each field is delimited by a tab except for the first which is followed by two or more tabs.

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

The modified string will have each field wrapped in HTML table tags, and be on its own, indented line as so.

"<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>

"

I tried using code like the following to do it.

$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]);
}

The problem is that the escaped characters (tabs and newlines) in the replacement array remain escaped in the destination string and I get the following string.

"\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"

Strangely, this line I tried earlier on does work:

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

Am I missing something? Any idea how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飘过的浮云 2024-10-27 08:57:29

您需要双引号或此处文档作为替换字符串 - PCRE 仅解析搜索字符串中的那些转义字符。

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

如果您将其更改为 preg_replace('/\t+/', '\t', $data) 您可以观察到您的主要问题 - PCRE 知道 \t 中搜索字符串代表一个选项卡,但不代表替换字符串中的选项卡。

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

这有点不协调,只是要记住一点。

You need double quotes or heredocs for the replacement string - PCRE only parses those escape characters in the search string.

In your working example preg_replace("/\t+/", "\t", $data) those are both literal tab characters because they're in double quotes.

If you changed it to preg_replace('/\t+/', '\t', $data) you can observe your main problem - PCRE understands that the \t in the search string represents a tab, but doesn't for the one in the replacement string.

So by using double quotes for the replacement, e.g. preg_replace('/\t+/', "\t", $data), you let PHP parse the \t and you get the expected result.

It is slightly incongruous, just something to remember.

音盲 2024-10-27 08:57:29

您的 $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 version: Problem is single quote in the $replacements and $patterns that should be double quote

Your $replacements array has all its strings decalred as single-quoted strings.
That means that escaped characters won't scape (except \').

It is not related directly to PCRE regular expressions, but to how PHP handles strings.

Basically you can type strings like these:

<?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 version: problem is single quotes in the $replacements and $patterns that should be double quotes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文