如何检查变量是否包含有效的 UTF-8 字符串而不带任何控制字符?

如何检查变量是否包含有效的 UTF-8 字符串而不带任何控制字符?

如何在 bash 中检查变量是否包含有效的 UTF-8 字符串,而不包含任何特殊控制字符(例如换行符、退格符或回车符等)?

答案1

假设区域设置使用 UTF-8 作为其字符编码(使用 进行检查locale charmap):

[[ $string =~ ^[^[:cntrl:]]*$ ]]

应该可以工作,除了至少在 GNU 系统上,它无法拒绝包含代码点高于 0x110000 的字符的 UTF-8 编码的字符串(这些字符是在 UTF-8 编码的当前定义中不再有效)。这取决于系统的正则表达式库bash用于进行模式匹配。

GNU 也是如此expr

expr " $string" : ' [^[:cntrl:]]*$' > /dev/null

在这里,您可能想要切换到zshUTF-8 语言环境中的位置:

set -o extendedglob
[[ $string = [' '-$'\ud7fff'$'\ue000'-$'\U10FFFF']# && $string != *[[:cntrl:]]* ]]

无论系统如何,都应该一致地工作(至少对于有效字符的匹配;您可能会发现字符被分类为 的系统之间存在差异[:cntrl:])。

在 zsh glob 模式中,多字节字符区域设置中的字符范围基于字符的宽字符值,在 UTF-8 中它始终是 Unicode 代码点。不构成有效字符一部分的字节将在 0xD800..0xDFFF UTF16 代理项对的第二部分中分配 0xDC80..0xDCFF 范围内的 wchar_t 值,这些代理项对不是字符(aUnicode 认可的通用方法能够处理任意字节序列)。

bash glob 模式中的字符范围处理大多是随机的,所以不能在这里使用。

您可能还想考虑如何处理非字符,私人使用字符,当前未在您的系统正在使用的 Unicode 版本中分配的字符。的概念控制对于 Unicode 来说,字符也相当模糊。是 U+202E RIGHT-TO-LEFT OVERRIDE 字符、U+FEFF BOM 字符、标签人物例如控制人物?

相关内容