Linux中有哪些POSIX规范

Linux中有哪些POSIX规范,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

创新互联建站拥有一支富有激情的企业网站制作团队,在互联网网站建设行业深耕10多年,专业且经验丰富。10多年网站优化营销经验,我们已为上1000家中小企业提供了成都网站制作、成都网站建设解决方案,按需设计,设计满意,售后服务无忧。所有客户皆提供一年免费网站维护!

POSIX规范

常见的正则表达式记法,其实都源于Perl,实际上,正则表达式从Perl衍生出一个显赫的流派,叫做PCRE(Perl Compatible Regular  Expression),『\d』、『\w』、『\s』之类的记法,就是这个流派的特征。但是在PCRE之外,正则表达式还有其它流派,比如下面要介绍的POSIX规范的正则表达式。

POSIX的全称是Portable Operating System Interface for  uniX,它由一系列规范构成,定义了UNIX操作系统应当支持的功能,所以“POSIX规范的正则表达式”其实只是“关于正则表达式的POSIX规范”,它定义了BRE(Basic  Regular Expression,基本型正则表达式)和ERE(Extended Regular  Express,扩展型正则表达式)两大流派。在兼容POSIX的UNIX系统上,grep和egrep之类的工具都遵循POSIX规范,一些数据库系统中的正则表达式也符合POSIX规范。

BRE

在Linux/Unix常用工具中,grep、vi、sed都属于BRE这一派,它的语法看起来比较奇怪,元字符『(』、『)』、『{』、『}』必须转义之后才具有特殊含义,所以正则表达式『(a)b』只能匹配字符串  (a)b而不是字符串ab;正则表达式『a{1,2}』只能匹配字符串a{1,2},正则表达式『a\{1,2\}』才能匹配字符串a或者aa。

之所以这么麻烦,是因为这些工具的诞生时间很早,正则表达式的许多功能却是逐步发展演化出来的,之前这些元字符可能并没有特殊的含义;为保证向后兼容,就只能使用转义。而且有些功能甚至根本就不支持,比如BRE就不支持『+』和『?』量词,也不支持多选结构『(…|…)』和反向引用『\1』、『\2』…。

不过今天,纯粹的BRE已经很少见了,毕竟大家已经认为正则表达式“理所应当”支持多选结构和反向引用等功能,没有确实太不方便。所以虽然vi属于BRE流派,但提供了这些功能。GNU也对BRE做了扩展,支持『+』、『?』、『|』,只是使用时必须写成『\+』、『\?』、『\|』,而且也支持『\1』、『\2』之类反向引用。这样,GNU的grep等工具虽然名义上属于BRE流,但更确切的名称是GNU  BRE。

ERE

在Linux/Unix常用工具中,egrep、awk则属于ERE这一派,。虽然BRE名为“基本”而ERE名为“扩展”,但ERE并不要求兼容BRE的语法,而是自成一体。因此其中的元字符不用转义(在元字符之前添加反斜线会取消其特殊含义),所以『(ab|cd)』就可以匹配字符串ab或者cd,量词『+』、『?』、『{n,m}』可以直接使用。ERE并没有明确规定支持反向引用,但是不少工具都支持『\1』、『\2』之类的反向引用。

GNU出品的egrep等工具就属于ERE流(更准确的名字是GNU ERE),但因为GNU已经对BRE做了不少扩展,所谓的GNU  ERE其实只是个说法而已,它有的功能GNU BRE都有了,只是元字符不需要转义而已。

下面的表格简要说明了几种POSIX流派的区别[1](其实,现在的BRE和ERE在功能上并没有什么区别,主要的差异是在元字符的转义上)。

几种POSIX流派的说明

流派说明工具
BRE(、)、{、}都必须转义使用,不支持+、?、|grep、sed、vi(但vi支持这些多选结构和反向引用)
GNU BRE(、)、{、}、+、?、|都必须转义使用GNU grep、GNU sed
ERE元字符不必转义,+、?、(、)、{、}、|可以直接使用,\1、\2的支持不确定egrep、awk
GNU ERE元字符不必转义,+、?、(、)、{、}、|可以直接使用,支持\1、\2grep –E、GNU awk

为了方便查阅,下面再用一张表格列出基本的正则功能在常用工具中的表示法,其中的工具GNU的版本为准。

常用Linux/Unix工具中的表示法

PCRE记法vi/vimgrepawksed
*****
+\+\++\+
?\=\??\?
{m,n}\{m,n}\{m,n\}{m,n}\{m,n\}
\b *\< \>\< \>\< \>\y \< \>
(…|…)\(…\|…\)\(…\|…\)(…|…)(…|…)
(…)\(…\)\(…\)(…)(…)
\1 \2\1 \2\1 \2不支持\1 \2

注:PCRE中常用\b来表示“单词的起始或结束位置”,但Linux/Unix的工具中,通常用\<来匹配“单词的起始位置”,用\>来匹配“单词的结束位置”,sed中的\y可以同时匹配这两个位置。

POSIX字符组

在某些文档中,你还会发现类似『[:digit:]』、『[:lower:]』之类的表示法,它们看起来不难理解(digit就是“数字”,lower就是“小写”),但又很奇怪,这就是POSIX字符组。不仅在Linux/Unix的常见工具中,甚至一些变成语言中都出现了这些字符组,为避免困惑,这里有必要简要介绍它们。

在POSIX规范中,『[a-z]』、『[aeiou]』之类的记法仍然是合法的,其意义与PCRE中的字符组也没有区别,只是这类记法的准确名称是POSIX方括号表达式(bracket  expression),它主要用在Unix/Linux系统中。POSIX方括号表示法与PCRE字符组的最主要差别在于:POSIX字符组中,反斜线\不是用来转义的。所以POSIX方括号表示法『[\d]』只能匹配\和d两个字符,而不是『[0-9]』对应的数字字符。

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

POSIX规范也定义了POSIX字符组,它近似等价于于PCRE的字符组简记法,用一个有直观意义的名字来表示某一组字符,比如digit表示“数字字符”,alpha表示“字母字符”。

不过,POSIX中还有一个值得注意的概念:locale(通常翻译为“语言环境”)。它是一组与语言和文化相关的设定,包括日期格式、货币币值、字符编码等等。POSIX字符组的意义会根据locale的变化而变化,下面的表格介绍了常见的POSIX字符组在ASCII语言环境与Unicode语言环境下的意义,供大家参考。

POSIX字符组

POSIX字符组说明ASCII语言环境Unicode语言环境
[:alnum:]*字母字符和数字字符[a-zA-Z0-9][\p{L&}\p{Nd}]
[:alpha:]字母[a-zA-Z]\p{L&}
[:ascii:]ASCII字符[\x00-\x7F]\p{InBasicLatin}
[:blank:]空格字符和制表符[ \t][\p{Zs}\t]
[:cntrl:]控制字符[\x00-\x1F\x7F]\p{Cc}
[:digit:]数字字符[0-9]\p{Nd}
[:graph:]空白字符之外的字符[\x21-\x7E][^\p{Z}\p{C}]
[:lower:]小写字母字符[a-z]\p{Ll}
[:print:]类似[:graph:],但包括空白字符[\x20-\x7E]\P{C}
[:punct:]标点符号[][!"#$%&'()*+,./:;<=>?@\^_`{|}~-][\p{P}\p{S}]
[:space:]空白字符[ \t\r\n\v\f][\p{Z}\t\r\n\v\f]
[:upper:]大写字母字符[A-Z]\p{Lu}
[:word:]*字母字符[A-Za-z0-9_][\p{L}\p{N}\p{Pc}]
[:xdigit:]十六进制字符[A-Fa-f0-9][A-Fa-f0-9]

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

注2:对应的Unicode属性请参考本系列文章已经刊发过的关于Unicode的部分。

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

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。


名称栏目:Linux中有哪些POSIX规范
网站地址:http://azwzsj.com/article/gigeii.html