有什么策略可以逃避角色实体?

时间:2009-12-15 07:59:43

标签: character-encoding escaping

我们正在对一系列英语语言文档(主要是科学文档)进行自然语言处理,并在通过各种组件携带非ANSI字符时遇到问题。文档可以是“ASCII”,UNICODE,PDF或HTML。我们无法在此阶段预测我们的链中会有哪些工具,或者它们是否允许ANSI以外的字符编码。甚至用UNICODE表示的ISO-Latin字符也会产生问题(例如在浏览器中显示不正确)。我们可能会遇到一系列符号,包括数学和希腊语。我们希望将这些“扁平化”为一个文本字符串,它将在多步处理(包括XML和正则表达式工具)中存活,然后可能在最后一步重新构建它(尽管它是语义而不是我们关注的排版,所以这是一个小问题)。

我很欣赏没有绝对的答案 - 在某些情况下,任何转义都可能发生冲突 - 但我正在寻找XML <![CDATA[ ...]]>的所有内容,这些内容将在大多数非递归XML操作中存活下来。诸如[之类的字符很糟糕,因为它们在正则表达式中很常见。所以我想知道是否有一种普遍采用的方法,而不是发明自己的方法。

一个典型的例子是“度”符号:

HTML Entity (decimal)   &#176;
HTML Entity (hex)   &#xb0;
HTML Entity (named)     &deg;
How to type in Microsoft Windows    Alt +00B0
Alt 0176
Alt 248
UTF-8 (hex)     0xC2 0xB0 (c2b0)
UTF-8 (binary)  11000010:10110000
UTF-16 (hex)    0x00B0 (00b0)
UTF-16 (decimal)    176
UTF-32 (hex)    0x000000B0 (00b0)
UTF-32 (decimal)    176
C/C++/Java source code  "\u00B0"
Python source code  u"\u00B0"

我们也可能会遇到TeX

$10\,^{\circ}{\rm C}$

\degree

所以反斜杠,cur and和美元是一个糟糕的主意。

我们可以使用例如:

这样的标记
__deg__
__#176__

这可能会奏效,但我很感激那些有类似问题的人的建议。

更新我接受@MichaelB坚持我们始终使用UTF-8。我担心我们的一些工具可能不符合,如果是这样,我会重新考虑这个。请注意,我原来的问题措辞不当 - 请阅读他的答案及其中的链接。

2 个答案:

答案 0 :(得分:4)

  • 让某人真正了解角色编码。看起来你没有,因为你没有正确使用术语。或者,read this
  • 不要酝酿你自己的逃生计划 - 它会给你带来更多的问题而不是解决。相反,将各种源编码规范化为UTF-8(实际上只是一种这样的转义方案,除了有效和标准化)并正确处理字符编码。如果你真的害怕高位,也许可以使用UTF-7。
  • 在这个时代,不能正确处理字符编码是不可接受的。如果一个工具没有,放弃它 - 它很可能在许多其他方面也是非常糟糕的质量代码,不值得麻烦使用。

答案 1 :(得分:1)

也许我没有正确解决问题,但我会创建一个非常独特的转义标记,不太可能被触及,然后用它来封装编码为base32字符串的实体。

最后,您可以通过单独的频道传输独特的标记及其编号,并在最后检查它们的存在和编号。

例如,

the value of the temperature was 18 cd48d8c50d7f40aeb6a164181b17feee EZSGKZY= cd48d8c50d7f40aeb6a164181b17feee

您的标记是一个uuid,并且该实体在base32中进行了&amp; deg编码。然后传递标记cd48d8c50d7f40aeb6a164181b17feee。它不会被破坏(如果它被破坏,你的过滤器可能会破坏任何由字母和数字组成的东西,但至少你可以排除它们,因为它们是固定的长度)并且你总是可以通过查看两个标记来恢复内容。

当然,如果你的文件中有uuids,这可能代表一个问题,但由于你没有将它们作为授权标记沿横向通道传输,它们将不会被识别出来(在任何情况下,什么是无论如何,inbetween不会验证为base32字符串。)

如果您需要搜索它们,那么您可以保留uuid细分,然后使用正确的正则表达式来发现这些事件。例如:

>>> re.search("(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*?)(\\1)", s)
<_sre.SRE_Match object at 0x1003d31f8>
>>> _.groups()
('6d378205-1265-44e4-80b8-a47d1ceaad51', ' EZSGKZY= ', '6d378205-1265-44e4-80b8-a47d1ceaad51')
>>> 

如果你真的需要一个特定的“令牌”来测试,你可以使用一个uuid1,它有一个非常明确的节点规范:

>>> uuid.uuid1(node=0x1234567890)  
UUID('bdcce554-e95d-11de-bd0f-001234567890')
>>> uuid.uuid1(node=0x1234567890)  
UUID('c4c57a91-e95d-11de-90ca-001234567890')
>>> 

你可以使用你喜欢的任何节点作为节点,uuid将是唯一的,但你仍然可以测试存在(虽然你可以得到误报)。