3 回答

TA貢獻1895條經(jīng)驗 獲得超3個贊
您可以使用回溯控制動詞 跳過部分字符串(*SKIP)
:
$result = preg_replace('~\\\\.(*SKIP)(?<=n)~', "\n", $source);
(*SKIP)
當(dāng)它之后的子模式失敗時,跳過它之前的子模式已經(jīng)到達(dá)的字符串的位置。(?<=n)
是一個回顧斷言,意思是前面有 n。當(dāng)它失敗時,正則表達(dá)式引擎跳轉(zhuǎn)到轉(zhuǎn)義字符位置(由 定義的位置(*SKIP)
)之后進行新的嘗試,而不是測試下一個位置(反斜杠之后的位置)。
您也可以使用以下方法執(zhí)行相同的操作strtr
:
$result = strtr($source, ['\\\\' => '\\\\', '\\n' => "\n"]);
(由于為兩個連續(xù)的反斜杠定義了替換,因此第二個反斜杠不能用于最終的后續(xù)n
.)

TA貢獻1891條經(jīng)驗 獲得超3個贊
您需要匹配成對的反斜杠\\或成對的\n. 通過指定回調(diào),您可以檢查是否需要替換它,如果不需要,只需逐字返回匹配的字符:
<?php
$inputs = [
"\n is [NewLine]",
"\\n is \n",
"\\\n is \[NewLine]",
"\n and \\n and \\\n and \\\\n"
];
$nl = function($matches) {
return $matches[0] == "\n" ? "[NewLine]" : $matches[0];
};
print_r(preg_replace_callback("/\\\\|\\n/", $nl, $inputs));
通過將\\first 放在正則表達(dá)式交替中,它將首先被消耗,并且只有當(dāng)反斜杠的數(shù)量為奇數(shù)時,才會\n匹配。
(確保轉(zhuǎn)義正則表達(dá)式模式中的反斜杠?。?/p>
最后一個示例輸入的輸出:[NewLine] and \n and \[NewLine] and \\n
如果您的輸入包含文字反斜杠字符和n(0x5c 0x6e) 而不是換行符 (0x0a)——那么您的輸入是真的\\n而不是\n——您需要添加一個額外的轉(zhuǎn)義級別。正則表達(dá)式變?yōu)?\\\\\\\\|\\\\n/回調(diào)必須檢查"\\n"

TA貢獻1820條經(jīng)驗 獲得超9個贊
找到了一個更簡單的解決方案。就像 knittl 所說的那樣,對匹配\是關(guān)鍵,而 regxp 并不是真正需要的。
strtr($input, ['\\\\' => '\\','\\n' => "[NL]"]);
$um = [
'\\\\' => '\\',
'\\n' => "[NL]",
];
$inputs = [];
for ($i=1;$i<=14;$i++) {
$inputs[] = ''.str_repeat("\\", $i)."n";
}
foreach ($inputs as $input) {
$results[] = strtr($input, $um);
}
foreach ($inputs as $key=>$value)
{
echo str_pad($value, 15, ' ',STR_PAD_LEFT)." =======> ".$results[$key]."\n";
}
輸出
\n =======> [NL]
\\n =======> \n
\\\n =======> \[NL]
\\\\n =======> \\n
\\\\\n =======> \\[NL]
\\\\\\n =======> \\\n
\\\\\\\n =======> \\\[NL]
\\\\\\\\n =======> \\\\n
\\\\\\\\\n =======> \\\\[NL]
\\\\\\\\\\n =======> \\\\\n
\\\\\\\\\\\n =======> \\\\\[NL]
\\\\\\\\\\\\n =======> \\\\\\n
\\\\\\\\\\\\\n =======> \\\\\\[NL]
\\\\\\\\\\\\\\n =======> \\\\\\\n
- 3 回答
- 0 關(guān)注
- 164 瀏覽
添加回答
舉報