Специальные (экранированные) символы в массиве замен в preg_replace экранируются - PullRequest
0 голосов
/ 06 марта 2011

Я пытаюсь изменить строку следующей формы, где каждое поле разделено вкладкой, за исключением первой, за которой следуют две или более вкладок.

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

1 голос
/ 06 марта 2011

В вашем массиве $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, которые должны быть в двойных кавычках

1 голос
/ 06 марта 2011

Вам нужны двойные кавычки или heredoc для строки замены - PCRE анализирует только эти escape-символы в строке поиска.

В вашем рабочем примере preg_replace("/\t+/", "\t", $data) это оба буквенные символы табуляции, потому что они в двойныхкавычки.

Если вы изменили его на preg_replace('/\t+/', '\t', $data), вы можете наблюдать свою главную проблему - PCRE понимает, что \t в строке поиска представляет собой вкладку, но не ту, что в строке замены.

Таким образом, используя двойные кавычки для замены, например, preg_replace('/\t+/', "\t", $data), вы позволяете PHP анализировать \t и получаете ожидаемый результат.

Это немного неуместно, просто что-то, что нужно запомнить.

...