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?
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\tin 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\tand you get the expected result.It is slightly incongruous, just something to remember.