0

我正在尝试使用 substr($originalText,0,250);从字符串中提取 n 个字符

第 n 个字符是一个破折号。所以当我在记事本中查看它时,我得到最后一个字符 â€。在我的编辑器 Brackets 中,我什至无法打开它的日志文件,因为它只支持 UTF-8 编码。

我也不能在这个字符串上运行 json_encode。

但是,当我使用 时substr($originalText,0,251),它工作得很好。我可以打开日志文件,它会显示一个破折号而不是â€。json_encode 也可以正常工作。

我可以mb_convert_encoding($mystring, "UTF-8", "Windows-1252")用来规避这个问题,但谁能告诉我为什么最后有这些字符会导致错误?此外,在执行此操作时,我的日志文件在括号中显示 â€,这也令人困惑。

我的问题是为什么在字符串末尾有破折号,与在其他任何地方都有不同(后跟其他字符)。

希望我的问题很清楚,如果不是,我可以尝试进一步解释。

谢谢。

4

2 回答 2

5

Pid 的回答解释了为什么会发生这种情况,这个答案只是看看你能做些什么......

使用 mb_substr()

字节字符串模块正是为这种情况而设计的,并提供了许多正确处理多字节字符的字符串函数。我建议您查看那里,因为在您的应用程序的其他地方可能还需要其他的。

如果您收到未找到功能的错误,您可能需要安装或启用此模块。这方面的说明是平台相关的,并且超出了这个问题的范围。

您对问题中的情况所需的函数被调用mb_substr(),并且调用方式与您将使用的相同substr(),但具有其他可选参数。

于 2016-10-14T13:28:42.333 回答
4

UTF-8使用所谓的代理将代码页扩展到 ASCII 之外以容纳更多字符。

根据字符的不同,单个 UTF-8 字符可以编码为一个、两个、三个或四个字节。

您在一个多字节字符的中间剪切字符串:

[<-character->]
[byte-0|byte-1]
       ^
      You cut the string right here in the middle!


[<-----character---->]
[byte-0|byte-1|byte-2]
       ^      ^
      Or anywhere here if it's 3 bytes long.

所以解码器有第一个字节但不能读取整个字符,因为字符串过早结束。

这会导致您目睹的所有影响。

这个问题的解决方案在 Dezza 的回答中。

于 2016-10-14T13:32:14.690 回答