我想知道是否可以使用 php 脚本将结尾行 mac (CR : \r) 转换为 windows (CRLF : \r\n)。
事实上,我有一个 php 脚本,它会在我的计算机上定期运行,以在 FTP 服务器上上传一些文件,并且在上传之前需要更改结尾行。手动完成很容易,但我想自动完成。
我想知道是否可以使用 php 脚本将结尾行 mac (CR : \r) 转换为 windows (CRLF : \r\n)。
事实上,我有一个 php 脚本,它会在我的计算机上定期运行,以在 FTP 服务器上上传一些文件,并且在上传之前需要更改结尾行。手动完成很容易,但我想自动完成。
您可以使用如下所示的简单正则表达式吗?
function normalize_line_endings($string) {
return preg_replace("/(?<=[^\r]|^)\n/", "\r\n", $string);
}
它可能不是最优雅或最快的解决方案,但它应该工作得很好(即它不会弄乱字符串中现有的 Windows (CRLF) 行尾)。
解释
(?<= - Start of a lookaround (behind)
[^\r] - Match any character that is not a Carriage Return (\r)
| - OR
^ - Match the beginning of the string (in order to capture newlines at the start of a string
) - End of the lookaround
\n - Match a literal LineFeed (\n) character
基本上将文件加载到字符串并调用类似:
function normalize($s) {
// Normalize line endings
// Convert all line-endings to UNIX format
$s = str_replace(array("\r", "\n"), "\r\n", $s);
// Don't allow out-of-control blank lines
$s = preg_replace("/\r\n{2,}/", "\r\n\r\n", $s);
return $s;
}
这是来自这里的一个片段,最后一个 regeg 可能需要进一步修改。
编辑:修复了删除重复替换的逻辑。
最后,更安全的方法是先更改您不想替换的内容,这里是我的功能:
/**Convert the ending-lines CR et LF in CRLF.
*
* @param string $filename Name of the file
* @return boolean "true" if the conversion proceed without error and else "false".
*/
function normalize ($filename) {
echo "Convert the ending-lines of $filename into CRLF ending-lines...";
//Load the content of the file into a string
$file_contents = @file_get_contents($filename);
if (!file_contents) {
echo "Could not convert the ending-lines : impossible to load the file.PHP_EOL";
return false;
}
//Replace all the CRLF ending-lines by something uncommon
$DontReplaceThisString = "\r\n";
$specialString = "!£#!Dont_wanna_replace_that!#£!";
$string = str_replace($DontReplaceThisString, $specialString, $file_contents);
//Convert the CR ending-lines into CRLF ones
file_contents = str_replace("\r", "\r\n", $file_contents);
//Replace all the CRLF ending-lines by something uncommon
$file_contents = str_replace($DontReplaceThisString, $specialString, $file_contents);
//Convert the LF ending-lines into CRLF ones
$file_contents = str_replace("\n", "\r\n", $file_contents);
//Restore the CRLF ending-lines
$file_contents = str_replace($specialString, $DontReplaceThisString, $file_contents);
//Update the file contents
file_put_contents($filename, $file_contents);
echo "Ending-lines of the file converted.PHP_EOL";
return true;
}
我对其进行了测试,但出现了一些错误:似乎没有替换 CR 结束行,而是添加了一个 CRLF 结束行,这是函数,我对其进行了一些修改以避免在此函数之外打开文件:
// FONCTION CONVERTISSANT LES FINS DE LIGNES CR TO CRLF
function normalize ($filename) {
echo "Convert the ending-lines of $filename... ";
//Load the file into a string
$string = @file_get_contents($filename);
if (!string) {
echo "Could not convert the ending-lines : impossible to load the file.\n";
return false;
}
//Convert all line-endings
$string = str_replace(array("\r", "\n"), "\r\n", $string);
// Don't allow out-of-control blank lines
$string = preg_replace("/\r\n{2,}/", "\r\n", $string);
file_put_contents($filename, $string);
echo "Ending-lines converted.\n";
return true;
}
删除所有 \r 字符然后将 \n 替换为 \r\n 可能更容易。
这将处理所有变化:
$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));