如何检测或正确识别陌生字符的长度?


How can I detect, or correctly identify the length, of strange characters?

我以编程方式将软连字符插入长单词,并且遇到不寻常字符的问题,特别是:■

任何超过10个字符的单词都得到软连字符处理。单词使用regex: [A-Za-z0-9,.]+定义(包括长数字)。如果我用正则表达式拆分一个包含上述两个unicode字符的字符串,我得到一个像这样的'word':■■

我的脚本然后遍历每个单词,测量长度(mb_strlen($word, 'UTF-8')),如果它超过任意数量的字符,循环遍历字母并在所有地方插入软连字符(每第三个字符,而不是最后五个字符)。

有了■■,字长就足够高,可以触发替换(10)。所以软连字符被插入,但是它们被插入字符中。所以我得到的结果是:

�­�■

在数据库中,这些■字符被存储(在json_encoded块中)为"'u2002",因此我可以看到字符串长度来自何处。我需要的是一种识别这些字符的方法,这样我就可以避免在包含这些字符的单词上添加软连字符。有什么想法吗?

(要么是这样,要么是一种测量字符串长度的方法,将这些字符计数为单个字符,然后将该字符串拆分为多个字符,而不需要通过多字节字符进行部分拆分。)

在没有看到代码的情况下猜测的注意事项与注释中列出的相同:

mb_strlen($word, 'UTF-8'),如果超过任意数量的字符,则循环遍历字母

我怀疑你实际上是在循环字节。如果在字符串上使用数组访问表示法,就会发生这种情况。

当你使用像UTF-8这样的多字节编码时,一个字母(或者更一般的"字符")可能占用超过一个字节的存储空间。如果你在字节序列的中间插入或删除,你会得到混乱的结果。

这就是为什么你必须使用mb_strlen而不是普通的旧strlen。有些语言有原生的Unicode字符串类型,其中每一项都是一个字符,但在PHP中字符串完全是基于字节的,如果您想以逐个字符的方式与它们交互,则必须使用mb_string函数。特别是从字符串中读取单个字符时,您使用mb_substr,并且将索引从0循环到mb_strlen

取匹配的单词并使用正则表达式替换在每个序列之间插入软连字符可能会更简单。您可以通过使用u标志来获得对regex的多字节字符串支持。(这只适用于UTF-8,但UTF-8是您真正想要使用的唯一多字节编码。)

const SHY= "'xC2'cAD"; // U+00AD Soft Hyphen encoded as UTF-8
$wrappableword= preg_replace('/.{3}'B/u', '$1'.SHY, $longword);