前面介绍了常用的字符组,但是在某些文档中,你可能会发现类似[:digit:]、[:lower:]之类的字符组,看起来不难理解(digit就是"数字",lower就是"小写"),但又很奇怪,它们就是POSIX字符组(POSIX Character Class)。因为某些语言的文档中出现了这些字符组,为避免困惑,这里有必要做个简要介绍。如果只使用常用的编程语言,可以忽略文档中的POSIX字符组,也可以忽略本节;如果想了解POSIX字符组,或者需要在Linux/UNIX下的各种工具(sed、awk、grep等)中使用正则表达式,最好阅读本节。

之前介绍的字符组,都属于Perl衍生出来的正则表达式流派(Flavor),这个流派叫做PCRE(Per Compatible Regular Expression)。在此之外,正则表达式还有其他流派,比如POSIX(Portable Operating System Interface for uniX),它是一系列规范,定义了UNIX操作系统应当支持的功能,其中也包括关于正则表达式的规范,[:digit:]之类的字符组就是遵循POSIX规范的字符组。

常见的[a-z]形式的字符组,在POSIX规范中仍然获得支持,它的准确名称是POSIX方括号表达式(POSIX bracket expression),主要用在UNIX/Linux系统中。POSIX方括号表达式与之前所说的字符组最主要的差别在于:在POSIX字符组中,反斜线\不是用来转义的。所以POSIX方括号表达式[\d]只能匹配\和d两个字符,而不是[0-9]对应的数字字符。

为了解决字符组中特殊意义字符的转义问题,POSIX方括号表达式规定:如果要在字符组中表达字符](而不是作为字符组的结束标记),应当让它紧跟在字符组的开方括号之后,所以[]a]能匹配的字符就是]或a;如果要在字符组中标识字符-(而不是"-范围表示法"),就必须将它放在字符组的闭方括号]之前,所以[a-]能匹配的字符就是a或-。

另一方面,POSIX规范还定义了POSIX字符组(POSIX character class),它大致等于之前介绍的字符组简记法,都是使用类似[:digit:]、[:lower:]之类有明确意义的记号表示某类字符。

表1-2简要介绍了POSIX字符组,注意表格中与其对应的是ASCII字符组,也就是能匹配的ASCII字符(ASCII编码表中码值在0~127之间的字符)。因为POSIX规范中有一个重要概念:locale(通常翻译为"语言环境"),它是一组与语言和文化相关的设定,包括日期格式、货币币值、字符编码等。POSIX字符组的意义会根据locale的变化而变化,表1-2介绍的只是这些POSIX字符组在ASCII编码中的意义;如果换用其他的locale(比如使用Unicode字符集),它们的意义可能会发生变化,具体请参考第129页。

表1-2  POSIX字符组

POSIX字符组

说明

ASCII字符组

等价的PCRE

简记法

[:alnum:]*

字母字符和数字字符

[a-zA-Z0-9]

 

[:ASCII:]

ASCII字符

[\x00-\x7F]

[:alpha:]

字母

[a-zA-Z]

 

[:blank:]

空格字符和

制表符

[ \t]

[:cntrl:]

控制字符

[\x00-\x1F\x7F]

[:digit:]

数字字符

[0-9]

\d

[:graph:]

空白字符之

外的字符

[\x21-\x7E]

[:lower:]

小写字母字符

[a-z]

[:print:]

类似[:graph:],但包括空白字符

[\x20-\x7E]

[:punct:]

标点符号

[][!"#$%&'()*+,./:;<=>?@\^_`{|}~-]

[:space:]

空白字符

[ \t\r\n\v\f]

\s

[:upper:]

大写字母字符

[A-Z]

[:word:]*

字母字符

[A-Za-z0-9_]

\w

[:xdigit:]

十六进制字符

[A-Fa-f0-9]

注:标记*的字符组简记法并不是POSIX规范中的,但使用很多,一般语言中都提供,文档中也会出现。

POSIX字符组的使用也与PCRE字符组简记法的使用有所不同,主要区别在于,PCRE字符组简记法可以脱离方括号直接出现,而POSIX字符组必须出现在方括号内。所以同样是匹配数字字符,PCRE中可以直接写\d,而POSIX字符组必须写成[[:digit:]]。

在本书介绍的6种语言中,Java、PHP、Ruby支持使用POSIX字符组。

在PHP中可以直接使用POSIX字符组,但是PHP中的POSIX字符组只识别ASCII字符,也就是说,任何非ASCII字符(比如中文字符)都不能由任何一个POSIX字符组匹配。

Ruby的情况稍微复杂一点。Ruby 1.8中的POSIX字符组只能匹配ASCII字符,而且不支持[:word:]和[:ASCII:];Ruby 1.9中的POSIX字符组可以匹配Unicode字符,而且支持[:word:]和[:ASCII:]。

Java中的情况更加复杂。POSIX字符组[[:name:]]必须使用\p{name}的形式,其中name为POSIX字符组对应的名字,比如[:space:]就应当写作\p{Space},请注意第一个字母要大写,其他POSIX字符组都是这样,只有[:xdigit:]要写作\p{XDigit}。并且Java中的POSIX字符组,只能匹配ASCII字符。

正则表达式——POSIX字符组的更多相关文章

  1. java正则表达式中的POSIX 字符类和Unicode 块和类别的类介绍

    假如现在有一个需求,要你用Java语言来匹配出一个文本里面的所有(英文半角)标点符号,你会怎么写呢?我想大多数人应该是把这些符号都罗列出来, 如: !"#$%&'()*+,-./:; ...

  2. [ ] 字符组(Character Classes) (转)

    []能够匹配所包含的一系列字符中的任意一个.需要注意的是,[]虽然能匹配其中的任意一个字符,但匹配的结果只能是一个字符,不是多个. 例如[abc]表示字符“a”或“b”或“c”. []支持用连字符“- ...

  3. C# -- 正则表达式匹配字符之含义

    C#正则表达式匹配字符之含义 1.正则表达式的作用:用来描述字符串的特征. 2.各个匹配字符的含义: .   :表示除\n以外的单个字符 [ ]  :表示在字符数组[]中罗列出来的字符任意取单个 | ...

  4. python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义

    本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...

  5. 正则指引-字符组demo

    class Program { static void Main(string[] args) { string str = "b"; var result1 = Regex.Is ...

  6. POSIX字符类

    POSIX字符类需要用引号,或双括号[[]]括起来: [:alnum:]:匹配字面和数字字符.等同于A~Z,a~z,0~9 [:alpha:]:匹配字母字符.等同于A~Z,a~z [:blank:]: ...

  7. c语言-三字符组

    C 源程序源字符集在 7 位 ASCII 字符集中包含,但设置为 ISO 646-1983 固定的代码的超集. 三字符序列允许 C 程序编写使用 " 仅 ISO (国际标准组织的固定的代码. ...

  8. Linux学习——shell编程之正则表达式和字符处理命令

    shell编程之正则表达式 一 正则表达式 1 什么是正则表达式 正则表达式用于描述字符排列和匹配模式的一种语法规则.它主要用于字符串的模式分隔.匹配.查找及替换操作. 2 shell编程之正则表达式 ...

  9. shell编程值之正则表达式与字符截取(6)

    正则表达式与通配符 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式 通配符用来匹配符合条件的文件名,通配符是完全匹配.ls.find.cp ...

随机推荐

  1. 使用Docker搭建Jumpserver堡垒机

    使用Docker搭建Jumpserver堡垒机 1.环境准备 操作系统:CentOS 7.6.1810 软件源:阿里云镜像 #内核版本(Docker 要求 CentOS 系统的内核版本高于 3.10) ...

  2. 关于Mysql group by 的记录

    对于有group by 字段的select语句,group by 后面的字段如果没有出现在组函数里(max,min,sum,avg, count等),则一定要出现在select后面的字段里, 否则会报 ...

  3. 北京师范大学第十五届ACM决赛-重现赛E Euclidean Geometry (几何)

    链接:https://ac.nowcoder.com/acm/contest/3/E 来源:牛客网 Euclidean Geometry 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ ...

  4. Set 的合集 并集 差集

    合集 ,,,,,,]; ,,]; function union() { //先将数组去重 let s1 = new Set(arr1); let s2 = new Set(arr2); //[...s ...

  5. Flutter-Radio單選框

    Container( child: Radio<String>( value: "男", activeColor: Colors.red,//激活時的顏色 groupV ...

  6. 从输入URL到页面加载到底发生了什么

    很多初学网络或者前端的初学者大多会有这样一个疑问:从输入URL到页面加载完成到底发生了什么?总的来说,这个过程分为下面几个步骤:1.DNS解析2.与服务器建立连接3.服务器处理并返回http报文4.浏 ...

  7. iOS各别版本new Date().getTime 获取时间戳为null问题

    正常逻辑 new Date('2019-9-8').getTime() 注意日期格式 yyyy--mm-dd 因为yyyy/mm/dd也有兼容性问题 但是各别iOS版本不支持 // IOS 获取时间戳 ...

  8. vueroute的router.addRoutes

    router.addRoutes(routes: Array<RouteConfig>)动态添加更多路由到路由器.参数必须是使用与routes构造函数选项相同的路径配置格式的Array .

  9. 关了浏览器再开,怎么session还在?

    关了浏览器session当然仍然存在,因为session是储存在服务器端的,而服务器是不可能知道你有没有关掉浏览器. 服务器只是简单的保持session接受用户请求,只有当session一段时间没有被 ...

  10. 2017南宁网络赛 Problem J Minimum Distance in a Star Graph ( 模拟 )

    题意 : 乱七八糟说了一大堆,实际上就是问你从一个序列到另个序列最少经过多少步的变化,每一次变化只能取序列的任意一个元素去和首元素互换 分析 : 由于只能和第一个元素去互换这种操作,所以没啥最优的特别 ...