多亏了Bergi的 comments ,我找到了一个解决方案:
Sole.log("שלום10Hello".Split("").map(c=>;'${c}': \\u${c.charCodeAt(0).toString(16).padStart(4,'0')}
).Join("\n"));可能有助于了解字符串是如何实际组成的,而不会出现奇怪的BIDI呈现,这就是Slice的工作原理.我猜你是need to add some ltr/rtl marks岁.
在阅读了 comments 中链接的页面后,我意识到Unicode格式提供了两种类型的键代码(LRM和RLM标记),它们在呈现时宽度为零,它们的目的是覆盖默认的方向流.
因此,当数字前面的第一个非空格相邻字符是RTL字符时,显式RTL字符会干扰数字的默认LTR行为.因此,当我在数字之前添加一个LRM BIDI控制字符时,它忽略了导致问题的RTL方向流覆盖.
需要考虑的一件事是:
我还了解到,如果紧跟在数字后面的是Ltr字符,则可能需要紧跟在数字后面的RLM控制字符(由于空格的中立性而忽略空格),因为如果一个句子的开头是一个RTL单词,后面跟一个(空格,LRM,数字,空格,Ltr单词),那么LRM流覆盖会将数字和后面的Ltr单词合并到一个单独的Ltr块中,这会反转数字和Ltr部分的显示,因为数字在Ltr块之前找到.因此,上面描述的字符串将呈现为:
数字、空格、Ltr单词、空格、RTL单词与预期的呈现方式形成对比.
我添加了一个代码示例来演示它:
var myInput = document.getElementById("myInput"),
Normal = document.getElementById("Normal"),
Fixed = document.getElementById("Fixed");
myInput.value = "שלום 10 hello";
Normal.innerHTML = myInput.value.substring( 0, 6 );
Normal.innerHTML += '<div style="display: inline-block;"></div>';
Normal.innerHTML += myInput.value.substring( 6, 14 );
Fixed.innerHTML =
myInput.value.replace("10",String.fromCodePoint("0x200E")+"10").substring( 0, 7 );
Fixed.innerHTML += '<div style="display: inline-block;"></div>';
Fixed.innerHTML += myInput.value.replace("10",String.fromCodePoint("0x200E")+"10"+String.fromCodePoint("0x200F")).substring( 7, 16 );
<input id="myInput" style="direction: rtl;width: 79px;">
<h3>Before the fix</h3>
<div id="Normal" style="background: #ffa0a0;width: fit-content;direction: rtl;display: inline-block;"> </div>
<h3>After the fix</h3>
<div id="Fixed" style="background: #a2ffa0;width: fit-content;direction: rtl;display: inline-block;"> </div>