我正在为项目使用双向文本(混合英语和希伯来语)。文本以HTML格式显示,因此有时需要LTR或RTL标记(‎
或‏
)才能使标点符号正确显示为“弱字符”。由于技术限制,源文本中不存在这些标记,因此我们需要添加这些标记,以使最终显示的文本显示正确。
例如,以下文字:(example: מדגם) sample
以从右到左的模式呈现为sample (מדגם :example)
。更正的字符串看起来像‎(example:‎ מדגם) sample
,并呈现为sample (מדגם (example:
。
我们希望动态插入这些标记,而不是重新编写所有文本。首先,这看起来很简单:只需在每个标点符号实例附加一个‎
即可。但是,一些需要动态修改的文本包含HTML和CSS。造成这种情况的原因是不幸的,也是不可避免的。
没有解析HTML / CSS,是否有一种已知的算法可以实时插入Unicode方向标记(伪强字符)?
答案 0 :(得分:1)
我不知道在没有解析它的情况下安全地将方向标记插入HTML字符串的算法。将HTML解析为DOM并操作文本节点是确保您不会在<script>
和<style>
标记内的文本中意外添加方向标记的最安全方法。
这是一个简短的Python脚本,可以帮助您自动转换文件。如有必要,逻辑应易于翻译成其他语言。我对您尝试编码的RTL规则不够熟悉,但您可以调整正则表达式'(\W([^\W]+)(\W)'
和替换模式ur"\u200e\1\2\3\u200e"
以获得预期结果:
import re
import lxml.html
_RE_REPLACE = re.compile('(\W)([^\W]+)(\W)', re.M)
def _replace(text):
if not text:
return text
return _RE_REPLACE.sub(ur'\u200e\1\2\3\u200e', text)
text = u'''
<html><body>
<div>sample (\u05de\u05d3\u05d2\u05dd :example)</div>
<script type="text/javascript">var foo = "ignore this";</script>
<style type="text/css">div { font-size: 18px; }</style>
</body></html>
'''
# convert the text into an html dom
tree = lxml.html.fromstring(text)
body = tree.find('body')
# iterate over all children of <body> tag
for node in body.iterdescendants():
# transform text with trails after the current html tag
node.tail = _replace(node.tail)
# ignore text inside script and style tags
if node.tag in ('script','style'):
continue
# transform text inside the current html tag
node.text = _replace(node.text)
# render the modified tree back to html
print lxml.html.tostring(tree)
输出:
python convert.py
<html><body>
<div>sample (מדגם ‎:example)‎</div>
<script type="text/javascript">var foo = "ignore this";</script>
<style type="text/css">div { font-size: 18px; }</style>
</body></html>