【发布时间】:2019-06-07 01:26:01
【问题描述】:
我们经常看到人们问为什么他们的字符串与他们的正则表达式不匹配的问题,有时答案归结为他们期望一个字符是字符类的一部分,而实际上不是,或者他们试图使用简写来表示一个存在于其他工具中但不属于 awk 语言的字符类(例如,\d 代表 [[:digit:]])。因此,考虑到这一点,我正在为 awk 中的哪些字符类中存在哪些字符的问题创建一个规范的答案。
【问题讨论】:
标签: awk
我们经常看到人们问为什么他们的字符串与他们的正则表达式不匹配的问题,有时答案归结为他们期望一个字符是字符类的一部分,而实际上不是,或者他们试图使用简写来表示一个存在于其他工具中但不属于 awk 语言的字符类(例如,\d 代表 [[:digit:]])。因此,考虑到这一点,我正在为 awk 中的哪些字符类中存在哪些字符的问题创建一个规范的答案。
【问题讨论】:
标签: awk
以下脚本将为您的语言环境生成数字范围 0- 127 列在第一个表中 http://www.asciitable.com/ 和 https://en.wikipedia.org/wiki/ASCII。对于print "\t" 输出的水平制表符,第一个参考使用 TAB,另一个 HT 作为缩写 - 我更喜欢 TAB,所以我在下面使用它。他们都使用Space 来表示print " " 的字符输出,所以我在下面也这样做了,尽管我更常将其称为“空白字符”:
$ cat prtCharClasses.awk
# From the gawk manual, https://www.gnu.org/software/gawk/manual/gawk.html#Bracket-Expressions:
# [:alnum:] Alphanumeric characters
# [:alpha:] Alphabetic characters
# [:blank:] Space and TAB characters
# [:cntrl:] Control characters
# [:digit:] Numeric characters
# [:graph:] Characters that are both printable and visible (a space is printable but not visible, whereas an ‘a’ is both)
# [:lower:] Lowercase alphabetic characters
# [:print:] Printable characters (characters that are not control characters)
# [:punct:] Punctuation characters (characters that are not letters, digits, control characters, or space characters)
# [:space:] Space characters (these are: space, TAB, newline, carriage return, formfeed and vertical tab)
# [:upper:] Uppercase alphabetic characters
# [:xdigit:] Characters that are hexadecimal digits
# \s Matches any whitespace character. Think of it as shorthand for ‘[[:space:]]’.
# \S Matches any character that is not whitespace. Think of it as shorthand for ‘[^[:space:]]’.
# \w Matches any word-constituent character—that is, it matches any letter, digit, or underscore. Think of it as shorthand for ‘[[:alnum:]_]’.
# \W Matches any character that is not word-constituent. Think of it as shorthand for ‘[^[:alnum:]_]’.
BEGIN {
asciiMax = (asciiMax == "" ? 127 : asciiMax)
numClasses = split("\
[[:alpha:]] \
[[:digit:]] \
[[:alnum:]] \
[[:lower:]] \
[[:upper:]] \
[[:xdigit:]] \
[[:punct:]] \
[[:cntrl:]] \
[[:graph:]] \
[[:print:]] \
[[:blank:]] \
[[:space:]] \
\\s \
\\S \
\\w \
\\W \
", classes)
# Map the control chars and white space in the 0-127 range to
# their abbreviations to make them visible in the output:
split("NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US Space", map)
map[128] = "DEL"
for (asciiNr=0; asciiNr<=asciiMax; asciiNr++) {
char = sprintf("%c", asciiNr)
chars[++numChars] = char
}
for (classNr in classes) {
class = classes[classNr]
for (charNr in chars) {
char = chars[charNr]
if ( char ~ class ) {
classChars[classNr,charNr]
}
}
}
for (classNr=1; classNr<=numClasses; classNr++) {
class = classes[classNr]
printf "%-12s =", class
for (charNr=1; charNr<=numChars; charNr++) {
if ( (classNr,charNr) in classChars ) {
char = chars[charNr]
printf " %s", (charNr in map ? map[charNr] : char)
}
}
print ""
}
}
这是 C 语言环境中字符 0-127 的输出,如果您有不同的语言环境,那么输出会有所不同,因此请运行上述脚本以查看您的语言环境中的内容:
$ awk -f prtCharClasses.awk file
[[:alpha:]] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z
[[:digit:]] = 0 1 2 3 4 5 6 7 8 9
[[:alnum:]] = 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z
[[:lower:]] = a b c d e f g h i j k l m n o p q r s t u v w x y z
[[:upper:]] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
[[:xdigit:]] = 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
[[:punct:]] = ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
[[:cntrl:]] = NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US DEL
[[:graph:]] = ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
[[:print:]] = Space ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
[[:blank:]] = TAB Space
[[:space:]] = TAB LF VT FF CR Space
\s = TAB LF VT FF CR Space
\S = NUL SOH STX ETX EOT ENQ ACK BEL BS SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ DEL
\w = 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
\W = NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US Space ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ ` { | } ~ DEL
请注意,\s、\S、\w 和 \W 是仅在某些工具中可用的扩展,例如GNU awk。 \d 和 \D 不在上面存在 - 这些是某些工具中可用的扩展,这些工具支持 PCRE 作为 [:digit:] 的简写,但不包括 awk 的任何变体。如果您想要 [:digit:] 的简写,那么 [0-9] 似乎可以跨语言环境移植,但我有待更正。
如果您需要查看数字 127 之后的字符,则可以在命令行中设置 asciiMax,例如:
$ awk -v asciiMax=255 -f prtCharClasses.awk
[[:alpha:]] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
[[:digit:]] = 0 1 2 3 4 5 6 7 8 9
[[:alnum:]] = 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
[[:lower:]] = a b c d e f g h i j k l m n o p q r s t u v w x y z µ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
[[:upper:]] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ
[[:xdigit:]] = 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
[[:punct:]] = ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © « ¬ ® ¯ ° ± ² ³ ´ ¶ · ¸ ¹ » ¼ ½ ¾ ¿ × ÷
[[:cntrl:]] = NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US DEL
[[:graph:]] = ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
[[:print:]] = Space ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
[[:blank:]] = TAB Space
[[:space:]] = TAB LF VT FF CR Space
\s = TAB LF VT FF CR Space
\S = NUL SOH STX ETX EOT ENQ ACK BEL BS SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ DEL ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
\w = 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
\W = NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US Space ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ ` { | } ~ DEL ¡ ¢ £ ¤ ¥ ¦ § ¨ © « ¬ ® ¯ ° ± ² ³ ´ ¶ · ¸ ¹ » ¼ ½ ¾ ¿ × ÷
【讨论】:
\w 和\W,但是\y 和\B 呢?根据我的评论回复 here
\< 和\> 而不是\y,而且我还没有使用过\B。在我的回答中,它们和转义序列之间的区别在于它们不是字符集,而是指示字符之间的边界 - 它们更像 ^ 和 $ 而不是 \s、\S、\w和\W。 Wrt 何时使用 - 如果您发布问题,我相信有人可以帮助您。