Unicode双向算法详解(bidi算法)(二)

作者:黄邦勇帅(原名:黄勇)2019-10-17

Unicode双向算法详解(bidi算法)(二)


本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

本文是对《C++语法详解》一书相关章节的增补,以增强读者对字符的理解,因为《C++语法详解》引用的标准过于老旧。

《C++语法详解》网盘地址:
https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

本文摘自本人所作《Unicode编码和双向算法(bidi)详解》网盘地址
链接:https://pan.baidu.com/s/1LLKv22jQPmeba1XUCm0xoQ?pwd=a3x8
提取码:a3x8

有兴趣的读者可参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

由于本人能力有限,文中难免有错漏之处,望广大读者指出更正,不胜感激


第5节 bidi算法详解

5.1 解析分段 (P系列算法)

1、P1

把文本拆分为单独的段落,然后对每个分段应用bidi算法的其他规则。在bidi算法中,分段是通过分段分隔符(U+2029)或适当的换行函数划分的,这些字符的类型为B。

2、P2

在分段中查找第一个类型为L、AL或R的字符,查找时跳过隔离启动器和与其相匹配的PDI之间的所有字符

3、P3

若在P2中找到了类型为AL或R的字符,则将分段的嵌入等级设置为1,否则,将其设置为0。

4、理解P系列算法:

1)、P系列算法用于在没有为分段明确指定分段方向(即基础方向)时为其设置嵌入等级,若明确设置分段方向为从左向右(L类型),则分段的嵌入等级为0,若明确的设置分段方向为从右向左(R类型),则分段的嵌入等级为1。

2)、P2查找到的字符通常是分段中的第一个强字符,也就是说弱字符、中性字符会被忽略,不会被用于确定分段的方向。

3)、P2规则会忽略隔离启动器,这是因为隔离启动器与中性字符相同,而P2规则是忽略中性字符的。注意:隔离启动器和与其相匹配的PDI之间的所有字符也会被忽略。

4)、注意:P2规则会忽略嵌入启动器,但不会忽略嵌入范围内的文本。

示例4:确定如下分段的嵌入等级

分段1:12 @ 34 [( RLI ספ PDI ab cd

分段2:12 @ 34 [( LRE ספ PDF ab cd

分段3:12 @ 34 [( LRO ספ PDF ab cd

解:

1、分段1:

  • 忽略弱字符1、2、3、4
  • 忽略中性字符@、[、(、以及空格
  • 忽略RLI、PDI
  • 忽略RLI和PDI之间的字符 ספ 。
  • 找到的第一个强字符为字符a,该字符的方向为L,因此,分段1的嵌入等级为0

2、分段2:

  • 忽略的弱字符、中性字符与分段1相同,同时,LRE会被忽略,但LRE之后的内容不会被忽略,因此,找到的第一个强字符为 פ,该字符的方向为R,因此,分段嵌入等级为1。

3、分段3:

  • 略的弱字符、中性字符与分段1相同,同时,LRO(注意:LRO也是嵌入启动器)会被忽略,但LRO之后的内容不会被忽略,因此,找到的第一个强字符为 פ,该字符的方向为R,因此,分段的嵌入等级为1。 █

5.2 解析定向格式化字符及嵌入等级(X系列算法)

注:本小节示例中的字符串应一律忽略空格,示例中的空格主要是为了使字符串更清晰

一、X系列算法需要使用的变量

1、定向状态栈(以下简称栈),该栈中包含以下条目:

  • 嵌入等级(embeddin level,简称EL)。最小值为0,最大为最大深度(max_depth),bidi规定,最大深度为125。
  • 定向重写状态(directional override status,简称DOS)。用于表示重写的状态(即LRO、RLO)
  • 定向隔离状态(directional isolate status,简称DIS)。用于表示隔离的状态(即LRI、RLI、FSI)

2、溢出隔离计数器(overflow isolate count,简称OIC)。该计数器用于保存无效的隔离启动器的数量,以及确定一个PDI是否匹配或终止一个隔离启动器。

3、溢出嵌入计数器(overflow embedding count,简称OEC)。该计数器用于保存无效的嵌入启动器的数量,以及确定一个PDF是否匹配或终止一个嵌入启动器。

4、有效隔离计数器(valid isolate count,简称VIC)。该计数器用于保存被判定为有效的(即,栈中定向隔离状态为true的项),且还没遇到匹配的PDI的隔离启动器的数量,该计数器还用于在不查看定向状态栈且溢出隔离计数为0的情况下,判断一个PDI是否与某个有效隔离启动器相匹配。当该计数器的值大于0时,遇到的PDI会终止与其匹配的隔离启动器的范围。

5、注意:没有使用有效嵌入计数器来判断PDF是否会遇到有效的嵌入启动器,因为这可通过检查定向状态栈上最后一个条目的定向隔离状态和条目的数量来判断,其方法为:若栈中最后一个条目的定向隔离状态为true,且隔离范围内没有嵌入条目,则PDF位于一个定向隔离范围内,且该PDF不匹配任何内容。若栈中最后一个条目的定向隔离状态为false,并且是栈中唯一的一个条目,则该条目是属于段落级别的,因此该PDF仍不匹配任何内容。

6、需要注意的是,一个PDI可以结束在该隔离范围内的嵌入启动器的范围。比如aa RLI bb RLE cc PDI dd PDF,其中的PDI过早的结束的RLE的作用范围,从而导至相应的PDF没有区配的嵌入启动器。

二、X系列算法总述

1、bidi算法的步骤中需要解析每个字符(包括定向格式化字符)的嵌入等级和最终类型,X系列算法主要讲解怎样解析定向格式化字符的初始嵌入等级,注意,没有解析最终类型,其最终类型在后续算法中进行。因为定向格式化字符是特殊字符,除了嵌入等级外,还有其他问题需要解决,比如嵌入的深度是否超过规定的最大深度125(即溢出),PDI是否有匹配的隔离字符等,因此,X系列算法除了嵌入等级需要解析外,还需解决定向格式化字符的其他问题。

2、注意:由X系列算法确定的嵌入等级不是最终的嵌入等级,这些嵌入等级还会在后续算法中进行调整。

3、通常嵌入字符、重写字符及其终止字符PDF不会影响最终的字符排序,因此,通常不需要解析这些字符的嵌入等级和最终类型,在算法X9中,会明确移除(但并未真正删除)这些字符,也就是说,本文所讲的bidi算法都未考虑这些字符的嵌入等级和最终类型。但是,有时需要对这些字符进行解析(即不移除这些字符),此时就需要对bidi的一系列算法进行相应的修改,比如,在 X7算法的最后,添加一步以将PDF的嵌入等级设置成栈中最后一个条目的嵌入等级等,其余W系列、N系列、I系列等算法都应做修改,具体怎样修改,详见后文。

4、由X5a、X5b、X5c、X6、X6a可知,隔离字符、终止隔离字符PDI、所有非定向格式化字符的嵌入等级最终都会被设置为栈中最后一个条目保存的嵌入等级,也就是说,所有字符的嵌入等级都是通过栈设置的,这意味着,修改栈中嵌入等级EL的值,就会影响字符嵌入等级的解析。

5、由X系列算法可知,栈中嵌入等级EL的值是通过定向格式化字符进行修改的,其他字符不会修改EL,这意味着,字符的嵌入等级是通过定向格式化字符进行设置的,通过定向格式化字符可改变其后的字符的嵌入等级,其余字符不会影响字符的嵌入等级(在之后对嵌入等级的调整除外)。比如,由X4可知,RLO会把一个新的嵌入等级压入栈,从而改变之后的字符的嵌入等级。

6、由规则X2、X3、X4、X5、X5a、X5b、X5c可知,嵌入、重写、隔离字符会提升之后的字符的嵌入等级。由规则X6a、X7可知,一个匹配的PDI或PDF会把嵌入等级返回到与之匹配的隔离、嵌入或重写字符之前的嵌入等级,注意,对于PDF和PDI有个前提条件,就是需要有与之匹配的嵌入、重写或隔离字符,比如,

aa LRI bb LRE cc PDI dd PDF ee

由于PDI的特殊作用,PDI会终结LRE的作用范围,因此,PDF并未与LRE相匹配,所以PDF并不能把嵌入等级返回到与之匹配的LRE之前的字符的嵌入等级(即与bb相同的嵌入等级)
再如

aa bb LRE cc PDI dd PDF ee

由于PDI没有与之匹配的隔离字符,因此,该PDI并不会终止LRE的作用范围,按规则6a-2,该PDI什么都不会做。

7、特别注意:由X6a可知,PDI不但会终止隔离启动器的作用范围(或作用域),还会终止在其中的未找到匹配PDF的嵌入启动器的作用范围,比如,aa RLI bb RLE cc PDI dd PDF
其中RLE的作用范围在PDI处便已结束,即,RLE的作用范围只有字符串cc,不包括之后的dd。

8、由算法X6可知,重写字符会把之后的字符类型强制重置为L或R类型,同时,由X5a、X5b、X5c、X6a可知,重写字符同样会把隔离字符和PDI的类型强制重置为L或R类型,因此,可得出结论,重写字符会把之后的字符类型强制重置为L或R类型,这是强制性行为。特别注意:由规则2-3、3-3、5a-5、5b-5可知,重写

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值