假设有一个类,比如:
[:digit:]
我希望输出结果是:
0123456789
注意,这个方法应该适用于所有POSIX字符类。以下是我尝试过的内容:
$ printf %s '[:digit:]'
[:digit:]
假设有一个类,比如:
[:digit:]
0123456789
注意,这个方法应该适用于所有POSIX字符类。以下是我尝试过的内容:
$ printf %s '[:digit:]'
[:digit:]
我相信有更好的方法,但这里是一种暴力方法:
for i in {0..127}; do
char=$(printf \\$(printf '%03o' "$i"))
[[ $char =~ [[:alpha:]] ]] && echo "$char"
done
==
代替正则表达式运算符=~
。 - glenn jackman==
更快? - Tom Fenechfor((i=0; i < 0x110000; i++)) {
printf "\U$(printf "%x" $i)\n";
} | grep -a '^[[:alpha:]]$'
$'E\U0301'
,它由两个代码点组成一个字形(此特定序列规范化为单个代码点É)。对于像马拉雅拉姆语这样完全依赖组合的语言,这尤其令人尴尬。
- 它在cntrl
类中存在一些问题,具体来说是换行符。
- Ruby字符,我似乎无法在Stack Overflow上呈现。幸运的是,这些通常已被弃用,转而采用适当的标记。
- 它很慢。$ seq 126 | awk '{printf "%c", $0}' | grep -o '[[:digit:]]'
0
1
2
3
4
5
6
7
8
9
POSIX字符类是内部定义的。对于grep
,您可以通过re_format手册找到它们。
我们不再生活在基于ASCII的世界中。例如,您可能会认为[[:digit:]]
只包括字符0
到9
。但是,它也可以包括字符٠
到٩
或包括字符۰
到۹
1甚至字符๐
到၉
。这完全取决于您使用的语言以及如何设置您的计算机。
此外,我们不能再假设一个字符等同于一个字节。字符现在可以包括多字节序列。使用八进制代码表示字符并将其翻译将无法正常工作。
这取决于您的计算机和操作系统。如果您正在使用TRS80或PDP11编写程序,则很可能仍在使用ASCII编码。因此,您可以翻转所有127(或256)种不同的编码数字方式。如果您使用Mac或Linux系统,则很可能使用用UTF8编码表示的Unicode字符点。[:digit:]
是否包含各种语言中的数字,这是一个很好的观点。字符编码只在考虑解决方案的特定实现时才相关。总的来说,这更像是一个请求澄清原始问题而不是一个答案的评论。 - chepner另一种“同样但不同”的方法,只是因为OP询问了POSIX字符类,而许多响应依赖于非POSIX组件。
据我所知,这种方法是100%的POSIX,尽管我可能会滥用printf
和awk
。
我不知道这是否适用于所有用例或语言环境,但在“POSIXLY”中,对于0-127,这似乎对我有效。它也通过了shellcheck
。
我想你可以根据需要扩展范围。虽然有点冗长,但我认为这是可读性的代价。
只需将:alpha:
更改为您选择的类即可。
#!/bin/sh
LC_ALL=C
i=0
true > members
while [ "$i" -le 127 ]
do
echo "$i" | awk '{ printf "%c", $0 }' | awk '/[[:alpha:]]/ { print }'
# echo "$i" | awk '{ printf "%c", $0 }' | grep '[[:alpha:]]'
i=$(( i + 1 ))
done >> members
printf "%s\n" "$(tr -d '\n' < members)"
它还有一个额外的优点,即最终输出可以被修改以用于其他用途。
jot
比seq
更方便和灵活。
jot -s '' 10 0 # print it numerically
jot -s '' -c 10 48 # print it via ASCII ordinals
0123456789
要打印ASCII中的大写和小写字母,请执行以下操作
jot -s '' -c 26 65 # 65 = 9^2 - 4^2 jot -s '' -c 26 97 # 97 = 3^4 + 2^4
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
——————————
更新:以下是如何将gawk
匹配POSIX
字符类到UTF-8
的概述(尽管我认为gawk
在几十个方面存在不匹配):
R
= UTF-16r
rogate 范围为 D800-DFFF
,
通过 floor( codepoint / 2^11 ) == 3^3
进行匹配
| A
= a
lpha
| U
= u
pper
| L
= l
ower
| M
= alnuM
| D
= d
igit
| X
= x
digit
| G
= g
raph
| P
= p
rint
| T
= punct
| C
= c
ntrl
| S
= s
pace
| B
= b
lank
48 RAU_M_XGP____
160 RAU_M__GP____
48 RA_LM_XGP____
160 RA_LM__GP____
80 R___MDXGP____
256 R______GPT___
8 R_______P__SB
8 R_________CSB
32 R_________CS_
224 R_________C__
1,024 R____________ # surrogates D[8-F][8-F][0-F]
6 _AU_M_XGP____
1,179 _AU_M__GP____
6 _A_LM_XGP____
1,346 _A_LM__GP____
31 _A__M__GP____ # in alpha and alnum but neither case
1 __U____GP____ # only in upper but neither alpha nor alnum
1 ___L___GP____ # only in lower but neither alpha nor alnum
10 ____MDXGP____ # just the ASCII digits matched
5,187 _______GPT___
252,248 _______GP____
18 ________P__SB
2 ________P__S_
6 ________P____ ***
1 __________CSB # horizontal-tab 0x09 \011 \t
5 __________CS_
190 __________C__
851,827 _____________
***
:: 有趣的是,从 gawk
的角度来看,这些属于 [[:print:]]
而不属于 [[:graph:]]
U+ 10B3A | 68,410 | [ ]
U+ 10B3B | 68,411 | [ ]
U+ 10B3C | 68,412 | [ ]
U+ 10B3D | 68,413 | [ ]
U+ 10B3E | 68,414 | [ ]
U+ 10B3F | 68,415 | [ ]