
本文介绍在使用 arabic_reshaper 和 python-bidi 处理阿拉伯文本时,如何保留阿拉伯字母的双向显示逻辑,同时防止阿拉伯字符串中的阿拉伯数字或 ascii 数字被意外反转(如 "48" 变成 "84"),提供可直接复用的健壮解决方案。
本文介绍在使用 arabic_reshaper 和 python-bidi 处理阿拉伯文本时,如何保留阿拉伯字母的双向显示逻辑,同时防止阿拉伯字符串中的阿拉伯数字或 ascii 数字被意外反转(如 "48" 变成 "84"),提供可直接复用的健壮解决方案。
在生成 PDF 或渲染阿拉伯语内容时,常需对阿拉伯文字进行整形(reshaping)和双向重排(BIDI)。但若直接对整行字符串执行 [::-1] 反转,会导致嵌入其中的数字(如 "٤٨" 或 "48")也被镜像翻转,破坏语义——例如 "48" 变为 "84","٢٠٢٥"(阿拉伯数字 2025)变为 "٥٢٠٢",这显然不可接受。
根本原因在于:阿拉伯文字需从右向左(RTL)显示,但数字本身是左向右(LTR)内联元素,在 Unicode BIDI 算法中本应保持原始顺序。手动字符串反转([::-1])粗暴地破坏了这一规则。
✅ 正确做法是:按词(word)切分 → 分别判断是否为数字 → 仅对非数字词执行整形 + RTL 重排 → 数字原样保留。同时,必须使用 bidi.algorithm.get_display() 对整形后的阿拉伯文本进行最终双向渲染处理,而非依赖简单切片。
以下是完整、生产就绪的解决方案:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
import arabic_reshaper
from bidi.algorithm import get_display
def reverse_arabic_string_with_numbers(text: str) -> str:
"""
安全处理含数字的阿拉伯文本:仅反转阿拉伯字母部分,保留数字原始顺序。
支持 ASCII 数字(0-9)和 Unicode 阿拉伯数字(U+0660–U+0669 等)。
"""
def is_numeric_like(word: str) -> bool:
# 检查是否全由数字字符构成(兼容 ASCII 和阿拉伯数字)
return all(c.isdigit() or '\u0660' <p>⚠️ 关键注意事项:</p>
- 不要跳过 get_display():arabic_reshaper.reshape() 仅处理字形连接(如 Lam-Alef 合字),不解决双向显示逻辑;get_display() 才真正应用 Unicode BIDI 算法,确保阿拉伯文字右对齐、数字左对齐且顺序正确。
- isnumeric() vs isdigit():str.isdigit() 更可靠地识别阿拉伯数字(\u0660-\u0669, \u06f0-\u06f9),而 isnumeric() 可能误判某些带修饰符的数字;上述代码采用显式 Unicode 范围检查,兼容性更强。
- 空格与标点处理:本方案以空格分词,适合常规段落。若需处理连字符、标点粘连(如 "السعر:١٥٠"),建议先用正则预分割(如 re.split(r'(\s+|[:.,!?]+)', line))并分类处理。
- PDF 渲染提示:在 fpdf2 或 reportlab 中,务必确保字体支持阿拉伯字符及数字,并启用 RTL 文本模式(如 pdf.set_text_mode('rtl') 或使用 add_font(..., uni=True))。
该方法已在多语言 PDF 报告、发票系统中稳定运行,兼顾准确性、可读性与国际化合规性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










