
本文介绍如何使用 arabic-reshaper 和 python-bidi 库,在对阿拉伯文本进行视觉重排(reshape)和双向显示(BIDI)时,精准保留数字原始顺序,防止数字如 "48" 被误翻转为 "84"。
本文介绍如何使用 `arabic-reshaper` 和 `python-bidi` 库,在对阿拉伯文本进行视觉重排(reshape)和双向显示(bidi)时,精准保留数字原始顺序,防止数字如 "48" 被误翻转为 "84"。
在生成 PDF 或渲染阿拉伯语内容时,常需对阿拉伯文字进行整形(reshape)和双向算法处理(BIDI),以确保从右向左(RTL)正确显示。但若直接对整行字符串执行 [::-1] 反转,会将嵌入的阿拉伯数字(如 "٤٨")或 ASCII 数字(如 "48")一并翻转,导致语义错误(例如 "48" → "84","٢٠٢٤" → "٤٢٠٢"),严重影响可读性与准确性。
正确做法是:按词(word)粒度分离文本,仅对非数字单词执行阿拉伯整形与 RTL 反转,而数字部分保持原序不变。以下是推荐的稳健实现:
import arabic_reshaper
from bidi.algorithm import get_display
def reverse_arabic_string_with_numbers(text: str) -> str:
"""
对含阿拉伯文与数字的多行字符串进行安全 RTL 处理:
- 按换行符分割行;
- 每行按空格分词;
- 数字词(isnumeric() 为 True)原样保留;
- 非数字词先 reshape,再反转字符顺序,最后用 get_display 生成可显示字符串。
"""
result_lines = []
for line in text.split('\n'):
words = line.split()
processed_words = []
for word in words:
if word.isnumeric(): # ✅ 精确识别纯数字(支持 Unicode 数字如 '١٢٣')
processed_words.append(word)
else:
# 整形 → 字符反转 → BIDI 显示适配
reshaped = arabic_reshaper.reshape(word)
reversed_arabic = reshaped[::-1]
displayed = get_display(reversed_arabic)
processed_words.append(displayed)
result_lines.append(' '.join(processed_words))
return '\n'.join(result_lines)
# 示例使用
t = "مرحبا 48 ومرحبا ٢٠٢٤"
output = reverse_arabic_string_with_numbers(t)
print(repr(output)) # 'ابحرم 48 ابحرم ٢٠٢٤'
⚠️ 关键注意事项:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- str.isnumeric() 可同时识别 ASCII 数字('123')和 Unicode 阿拉伯-印度数字('١٢٣'),比 str.isdigit() 更全面;
- 切勿对整行调用 [::-1] —— 这会破坏数字顺序及混合文本的逻辑结构;
- get_display() 是必需步骤,它应用 Unicode 双向算法(UAX#9),确保整形后的阿拉伯字符在终端/PDF 中真正从右向左渲染;
- 若原文含标点(如 ،、؟)或混合英文,建议进一步增强分词逻辑(例如使用正则 \S+ 提取 token),但基础场景中空格分词已足够可靠。
总结:阿拉伯文本与数字共存时,必须采用“分而治之”策略——隔离数字、专注处理文字。该方法兼顾准确性、可维护性与跨数字体系兼容性,是 PDF 生成、Web 渲染等实际项目中的推荐实践。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










