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

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











