+----+----------------------------------------------------------------------+
| | 规则表达式之字符类 |
+----+--------------+------------------------+------------------------------+
| 01 | [[:alpha:]] | 字母符号 | ([A-Za-z])
| 02 | [[:alnum:]] | 字母数字 | ([[:alpha:][:digit:]) == ([A-Za-z0-9])
| 03 | [[:word:]] | 标识符(字母数字+下划线) | ([[:alnum:]_]) == ([A-Za-z0-9_])
| 04 | [[:punct:]] | 标点符号 | ([!"#$%&’()*+,\-./:;<=>?@[\\\]^_`{|}~])
| 05 | [[:graph:]] | 可见符号 | ([[:alnum:][:punct:]]) ==
([A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])
| 06 | [[:print:]] | 可打印符号(可见符号+空格) | ([[:graph:] ]) == ([[:alnum:][:punct:] ])
| 07 | [[:blank:]] | blank | ([\t ])
| 08 | [[:space:]] | whitespace | ([\t\n\v\f\r ])
| 09 | [[:lower:]] | lower case | ([a-z])
| 10 | [[:upper:]] | upper case | ([A-Z])
| 11 | [[:digit:]] | digits | ([0-9])
| 12 | [[:xdigit:]] | hex digit | ([0-9A-Fa-f])
| 13 | [[:ascii:]] | ASCII | ([\x00-\x7F])
| 14 | [[:cntrl:]] | control | ([\x00-\x1F\x7F])
+----+--------------+-----------------+-------------------------------------+
举例来说:
text := "abc123XXX"
fmt.Printf("%q\n", regexp.MustCompile(`[[:digit:]]`).FindAllString(text, -1))
// ["1" "2" "3"]
fmt.Printf("%q\n", regexp.MustCompile(`[[:alpha:]]+`).FindAllString(text, -1))
// ["abc" "XXX"]
一个题外话:为什么要用两层方括号([[]])
,用一层不行吗?
其实这个很容易理解,如果是一层方括号,因为一层方括号已经有语义了,就是任选其中的字符,比如[:alpha:]
匹配的是任意字符(':', 'a', 'l', 'p', 'h')
,也就是说[:alpha:]
==[:alph]
(去掉重复的':'
和'a'
),这样[:alpha:]
并没有被解析成想要的alphabetic letter
,而只是列出的那几个字母的选择。
因此:
[[:alpha:]]==[a-zA-Z]
然后还可以组合,像下面这些表达式含义是一样的:
- [[:alpha:][:digit:]]
- [[:alpha:]0-9]
- [a-zA-Z0-9]
所以如果是一层方括号,那么就按照普通的[xyz]
字符类(character class)来解析,如果是两层方括号,那么里面层的方括号就会按照命名的ASCII character class
被解开。
还是举个例子:
text := "abc123:ph"
fmt.Printf("%q\n", regexp.MustCompile(`[[:alpha:]]+`).FindAllString(text, -1))
// ["abc" "ph"]
fmt.Printf("%q\n", regexp.MustCompile(`[:alpha:]+`).FindAllString(text, -1))
// ["a" ":ph"]
fmt.Printf("%q\n", regexp.MustCompile(`[:alph]+`).FindAllString(text, -1))
// ["a" ":ph"]
网友评论