Php 如何检测或正确识别奇怪字符的长度?

Php 如何检测或正确识别奇怪字符的长度?,php,regex,unicode,utf-8,Php,Regex,Unicode,Utf 8,我正在通过编程方式将软连字符插入到长单词中,并且遇到了不寻常字符的问题,特别是:■ 任何超过10个字符的单词都会得到软连字符处理。单词用正则表达式定义:[a-Za-z0-9,.]+(包括长数字)。如果我用该正则表达式拆分一个包含上述两个unicode字符的字符串,我会得到一个“word”,如下所示:■■ 然后,我的脚本遍历每个单词,测量长度(mb_strlen(

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

任何超过10个字符的单词都会得到软连字符处理。单词用正则表达式定义:
[a-Za-z0-9,.]+
(包括长数字)。如果我用该正则表达式拆分一个包含上述两个unicode字符的字符串,我会得到一个“word”,如下所示:■■

然后,我的脚本遍历每个单词,测量长度(
mb_strlen(
),如果超过任意数量的字符,则循环遍历字母并在所有位置插入软连字符(每三个字符,而不是最后五个字符)

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

�­�■
在数据库中,这些■ 字符(在json_编码的块中)存储为“\u2002”,因此我可以看到字符串长度的来源。我需要的是一种识别这些字符的方法,这样我就可以避免在包含这些字符的单词中添加软连字符。有什么想法吗


(或者是一种测量字符串长度的方法,将其作为单个字符计算,然后是一种将该字符串拆分为多个字符而不通过多字节字符进行部分拆分的方法。)

具有与注释中列出的关于猜测而不查看代码相同的注意事项:

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

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

当您使用UTF-8等多字节编码时,一个字母(或更一般的“字符”)可能会占用多个字节的存储空间。如果在字节序列的中间插入或删除,则会产生错误的结果。

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

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


那么您将您的处理应用于
json_encode
d文本,而不是“真正的”UTF-8文本?如果是这样,为什么不先对文本进行
json\u解码
,然后进行处理,然后再对处理后的文本进行
json\u编码
?因为
mb_strlen(“■■", 'UTF-8')
应该返回正确的字符长度:
2
。据我所知,多字节编码可能会对regex产生问题。莫勒博士:我将单词视为一个数组,并循环遍历字母。每隔三个字符,我添加一个连字符。vstm:处理将应用于解码文本。但你是对的-我刚刚对con进行了手动测试就像你做的那样,从
mb_strlen
开始的长度是正确的。可能还有其他问题。我想你需要发布一些代码。我不知道\u2002(U+2002 EN空格)如何与regexp匹配,也不知道它如何转换为U+25A=黑色正方形“■”, 更不用说在字符中插入字符意味着什么了。我也不认为在每三个字母后任意插入软连字符有什么意义。这在我所知道的任何语言中都是不正确的。是的,就是这样-我在循环字节。非常感谢!
const SHY= "\xC2\cAD"; // U+00AD Soft Hyphen encoded as UTF-8
$wrappableword= preg_replace('/.{3}\B/u', '$1'.SHY, $longword);