如何在 bash 中检查变量是否包含没有任何特殊控制字符(例如换行符或退格符或回车符等)的有效 UTF-8 字符串?
Sté*_*las 12
如果语言环境使用 UTF-8 作为其字符编码(检查locale charmap
):
[[ $string =~ ^[^[:cntrl:]]*$ ]]
Run Code Online (Sandbox Code Playgroud)
应该可以工作,但至少在 GNU 系统上,它无法拒绝包含 UTF-8 编码字符的字符串,其代码点高于 0x110000(在 UTF-8 编码的当前定义中不再有效)。这取决于系统的正则表达式库bash
用于进行模式匹配。
这对 GNU 来说是一样的,expr
并且:
expr " $string" : ' [^[:cntrl:]]*$' > /dev/null
Run Code Online (Sandbox Code Playgroud)
在这里,您可能想要切换到zsh
UTF-8 语言环境中的位置,
[[ $string =~ ^[^[:cntrl:]]*$ ]]
Run Code Online (Sandbox Code Playgroud)
无论系统如何,都应该始终如一地工作(至少对于有效字符的匹配;您可能会发现字符被归类为 的系统之间的差异[:cntrl:]
)。
在 zsh glob 模式中,多字节字符区域设置中的字符范围基于字符的宽字符值,在 UTF-8 中,它始终是 Unicode 代码点。不构成有效字符一部分的字节在 0xD800..0xDCFF 范围内的 0xD800..0xDFFF UTF16 代理项对的第二部分中分配了 wchar_t 值,这些值不是字符(Unicode 认可的一种通用方法,能够处理任意字节序列)。
bash glob 模式中的字符范围处理主要是 random,所以不能在这里使用。
您可能还需要考虑如何处理非字符、私人使用字符、当前未在您的系统正在使用的 Unicode 版本中分配的字符。当涉及到 Unicode 时,控制字符的概念也相当模糊。U+202E RIGHT-TO-LEFT OVERRIDE 字符、U+FEFF BOM 字符、标签字符例如控制字符?