加号(+)是基本正则表达式的一部分吗?

时间:2018-12-26 05:34:05

标签: regex sed standards

最近我被告知,+(一个或多个出现的前一个模式/字符)不是基本正则表达式的一部分。即使写成\+也没有。

这是关于最大兼容性的问题。

我的印象是...

echo "Hello World, I am an example-text" | sed 's#[^a-z0-9]\+#.#ig'

...始终导致:

Hello.World.I.am.an.example.text

但是后来我被告知,“它替换了每个小写字符,而不是小写字母或数字,后跟+”,并且它与[^a-z0-9][+]相同。

所以我真正的问题是:是否有没有将x+x\+xx*相同的正则表达式定义或实现?

2 个答案:

答案 0 :(得分:5)

POSIX“基本”正则表达式不支持+ (也不支持?!)。 sed的大多数实现都添加了对\+的支持,但这不是POSIX标准功能。如果您的目标是最大的可移植性,则应避免使用它。请注意,您必须使用\+而不是更常见的+

echo "Hello World, I am an example-text" | sed 's#[^a-z0-9]\+#.#ig'

-E标志启用“扩展”正则表达式,该表达式与Perl,JavaScript和大多数其他现代正则表达式引擎中使用的语法非常接近。使用-E,您不需要反斜杠;就是+

echo "Hello World, I am an example-text" | sed -E 's#[^a-z0-9]+#.#ig'

来自https://www.regular-expressions.info/posix.html

  

POSIX或“ uniX的便携式操作系统接口”是一组标准,这些标准定义了(UNIX)操作系统应支持的某些功能。这些标准之一定义了两种正则表达式。涉及正则表达式的命令(例如grep和egrep)在符合POSIX的UNIX系统上实现这些风味。一些数据库系统也使用POSIX正则表达式。

     

基本正则表达式或BRE风格对一种风格进行了标准化,该风格类似于传统UNIX grep命令所使用的一种。这几乎是当今仍在使用的最古老的正则表达式。 使这种风味与众不同的一件事是,大多数元字符都需要加一个反斜杠来赋予其元字符自己的风味。大多数其他风味(包括POSIX ERE)都使用反斜杠来抑制元字符的含义。使用反斜杠转义从未使用过元字符的字符是错误的。

     

BRE支持POSIX括号表达式,该表达式类似于其他正则表达式中的字符类,并具有一些特殊功能。不支持速记。使用常规元字符的其他功能包括:点以匹配换行符以外的任何字符;插入号和美元匹配字符串的开头和结尾;星号将令牌重复零次或更多次。要从字面上匹配任何这些字符,请使用反斜杠将其转义。

     

其他BRE元字符要求使用反斜杠以赋予其特殊含义。原因是UNIX grep的最旧版本不支持这些版本。 grep的开发人员希望使其与现有的正则表达式兼容,后者可以将这些字符用作文字字符。 BRE a{1,2}从字面上匹配a{1,2},而a\{1,2\}匹配aaa某些实现支持\?\+作为\{0,1\}\{1,\}的替代语法,但是\?\+不属于令牌可以与\(\)分组。后向引用是通常的\1\9。最多允许9组。例如。 \(ab\)\1匹配abab,而(ab)\1无效,因为没有对应于反向引用\1.的捕获组。使用\\1可以从字面上匹配\1。 / p>      

POSIX BRE不支持任何其他功能。甚至不支持交替。

(强调我的。)


  

所以我真正的问题是:是否有没有将x+x\+xx*相同的正则表达式定义或实现?

我想不出任何既不支持+也不支持\+的现实语言或工具。

formal mathematical definition of regular expressions中,通常只定义了三个操作:

  1. 串联: AB 匹配 A ,然后匹配 B
  2. 替代项 A | B 匹配 A B
  3. 亚芳星: R * 匹配0个或多个 R 重复。

这三个操作足以赋予正则表达式完整的表达能力。像 + 这样的运算符在编程中很方便,但在数学上下文中不是必需的。如果需要,可以根据其他术语进行定义: R? R |ε R + RR *


†从数学上讲,即。形式语言理论中不存在诸如向后引用和向前/向后查找之类的功能。这些功能增加了正则表达式的数学定义中无法提供的附加表达能力。

答案 1 :(得分:1)

在某些传统的sed实现中,您必须启用“扩展”正则表达式才能获得对+表示“一个或多个”的支持。

有关这方面的证据,请参见:sed plus sign doesn't work