网页中的字符乱七八糟(尤其是社交媒体)

Messed up characters in webpages (especially social media)

你们中的许多人可能已经看到 'trolls' 在社交媒体网站、论坛或视频流网站(例如 youtube)上发布弄乱整个网页的奇怪字符。

附上一个例子,一张我从 Instagram 截取的图片,显示用户发布的评论弄乱了整个评论部分。

这怎么可能?为什么会这样?我们如何才能防止类似的事情发生在我们的网站上?

How is such a thing possible?

Unicode 允许以两种方式使用变音符号。

第一种是“组合”形式,其中有一个字符用于组合字母和变音符号,例如 U+00E9 带尖音符号的拉丁文小写字母 E é.

第二种是“分解”形式,其中您有一个字符作为基本字母,然后是一个单独的“组合变音”字符。文本处理器 and/or 字体将这些字符的组合呈现为一个字素,例如 U+0065 Latin Small Letter E 后跟 U+0301 Combining Acute 。这样做的优点(也可以说是缺点)是您可以编写没有组合字符的组合(通常是因为它们从未在任何真实语言中使用过),例如 .

允许在单个字母上使用多个组合变音符号,因为有些语言在一个字母上使用多个重音符号(以及使用其他组合字符的技巧,例如韩语 Jamo 和藏语连接字母) .可以使用多少个组合字符来构成一个字素没有固有的限制。

许多文本处理器会尝试通过将多个组合变音符号堆叠在一起(以及在另一个方向上,用于“下方”重音)来布置多个组合变音符号。通常,这是一种合理的方式来尝试显示使用的字体没有特定字形的多重重音字母。但这确实意味着您可以疯狂地使用荒谬数量的变音符号来装饰正常文本行之外的方式。

how can we prevent things like that from happening in our website?

简单的解决方案是用 CSS overflow: hidden 将每个评论放在自己的块中,这样它们就无法转义到其他内容。

另一种可能性是过滤多个组合字符序列的输入。例如,使用正则表达式,您可以删除:

\p{M}{9,}

因为8是目前自然语言中已知的组合器longest sequence。如果您只关心简单的字母表,则可以尝试使用较小的数字。为此,您需要一个支持 Unicode 字符 classes (\p) 的正则表达式引擎,某些语言本身不支持。如果你的语言没有这个,但你可以访问 Unicode 数据库(例如 Python 中的 unicodedata),你可以手动遍历字符以查找具有 M 字符 class.