PHP读取RTF换行不一致的根本原因是RTF用\par、\line等控制字而非标准换行符表示换行,且编辑器导出格式混杂;必须先用rtf2text等库解析提取纯文本,再统一换行符,不可直接正则替换。

PHP 读取 RTF 文件时换行符不一致,根本原因在于 RTF 格式本身不直接存储标准的 \n 或 \r\n,而是用控制字(如 \line、\par)表示段落和换行,且不同编辑器导出的 RTF 可能混用 \r、\n、\r\n 甚至 Unicode 换行符(如 U+2028、U+2029)。直接用 file_get_contents() 读取后不做解析,就会看到乱码或换行丢失。
先剥离 RTF 控制指令,提取纯文本再处理换行
RTF 是标记语言,不能当纯文本直接正则替换。必须先解码为可读文本,再标准化换行:
- 用成熟库(如 rtf-html-php 或轻量级
rtf2text类)解析 RTF 结构,把\par转成\n,\line转成\n(或\n+ 空格,视需求而定) - 避免手写正则匹配
\\par—— RTF 有嵌套、转义、注释({\*)、字符集声明等,正则极易误伤 - 示例(使用
rtf2text类):$text = rtf2text::convert(file_get_contents('doc.rtf'));$text = str_replace(["\r\n", "\r"], "\n", $text); // 统一为 LF
若必须手动预处理原始 RTF 字符串
仅限简单 RTF(无字体、样式、图片),且你确认格式干净:
- 先移除 RTF 头部(
{\rtf1\ansi\ansicpg936\...})和尾部大括号,保留主体内容 - 将常见换行控制字替换为换行符:
$rtf = preg_replace('/\\\\par(\s|})/', "\n$1", $rtf);$rtf = preg_replace('/\\\\line(\s|})/', "\n$1", $rtf); - 再清理残留控制字、十六进制编码(如
'\u4f60')、空格缩进,最后统一换行:$text = preg_replace('/[\r\n\t]+/', "\n", $text);$text = trim($text);
输出前强制标准化,适配不同环境
即使输入已统一为 \n,显示或写入文件时仍需按目标平台调整:
立即学习“PHP免费学习笔记(深入)”;
- Web 输出:换行需转为
或用nl2br(),否则 HTML 忽略换行符 - 写入 TXT 文件:Windows 用
\r\n,Linux/macOS 用\n,可用PHP_OS_FAMILY判断:$eol = PHP_OS_FAMILY === 'Windows' ? "\r\n" : "\n";$text = str_replace("\n", $eol, $text); - 存入数据库:统一用
\n存储,读取时按需转换,避免字段值被操作系统干扰
不复杂但容易忽略:RTF 的换行逻辑在语义层(段落 vs 行内换行),不是字节层。靠 string 替换治标不治本,优先走解析路线。











