折叠的 unicode 安全替代方案

Chr*_*ski 6 sed fold

我正在使用fold -w 3将一行拆分为多个 3 个字符长,但是对于 GNU 实现,它似乎不适用于具有多字节字符的文本。

我怎样才能实现上述目标sed

我想出了sed -r 's/^(.{0,3})(.*)/\1\n\2/g'但是这只会做一个替换:

echo "111222333444555666" | sed -r 's/^(.{0,3})(.*)/\1\n\2/g' 
111
222333444555666
Run Code Online (Sandbox Code Playgroud)

附加示例:

echo "???????????????????????" | sed -r 's/^(.{0,3})(.*)/\1\n\2/g' 
???
????????????????????
Run Code Online (Sandbox Code Playgroud)

并且fold它的破坏行为:

echo "???????????????????????" | fold -w 3                         
??
??
??
??
??
Run Code Online (Sandbox Code Playgroud)

Rom*_*est 7

简短的grep方法:

echo "???????????????????????" | grep -Eo '.{1,3}'
???
???
???
???
???
???
???
??
Run Code Online (Sandbox Code Playgroud)

只保留 3 个字符的序列: ... | grep -Eo '.{3}'


Sté*_*las 6

请注意,问题不在于 Unicode 字符集,而在于使用 2 个或更多字节编码的字符(以及宽度不是一个单元格的字符)。

\n

UTF-8 是 Unicode 的一种编码,其中字符 U+0080 到 U+10FFFFF 在 2 个或更多字节上进行编码。Unicode 字符 U+0000 到 U+007F 与 ASCII 中的相同,而 UTF-8 中的字符编码在单个字节上(与 ASCII 中相同),因此在这里不是问题。

\n

Unicode 字符集还有其他编码(例如 iso8859-1,单字节但仅限于字符 U+0000 到 U+00FF,或 GB18030,多字节),还有其他多字节的非 Unicode 字符集编码。

\n

您可以使用该命令了解您的语言环境中使用的字符编码locale charmap

\n

目前,GNU 实现fold只能正确处理单字节字符。大多数fold其他系统不存在这个问题。许多甚至可以处理零或双倍显示宽度的字符。

\n

自 2010 年起, busybox 实现fold就支持 UTF-8(但不支持其他多字节字符映射)。

\n\n

U+0301 是一种组合锐音。它具有空宽度,并且在 UTF-8 中以 2 个字节 (0xcc 0x81) 进行编码。因此,\xc3\xa1( $'a\\u0301') 是一个宽度为 1 的字素簇,由 3 个字节编码的 2 个字符组成,因此有 3 种不同的行为,其中最正确的是 FreeBSD/Solaris 的行为。

\n

grep使用带有 PCRE 支持、UTF-8 语言环境和 UTF-8 输入构建的GNU :

\n
grep -Po '\\X{1,3}'\n
Run Code Online (Sandbox Code Playgroud)\n

在输入的每一o行上输出 1 到 3(尽可能多)的所有序列 eX倾向于字素簇,对于上述将标记与单宽字符组合的情况,可能会给您更好的结果。

\n

如果存在双角字符或不与单角字符组合的零字符,或者存在 TAB、CR、BS 等控制字符,则无济于事。

\n