最近我被告知,+
(一个或多个出现的前一个模式/字符)不是基本正则表达式的一部分。即使写成\+
也没有。
这是关于最大兼容性的问题。
我的印象是...
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*
相同的正则表达式定义或实现?
答案 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\}
匹配a
或aa
。 某些实现支持\?
和\+
作为\{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中,通常只定义了三个操作:
这三个操作足以赋予正则表达式完整的表达能力†。像?和 + 这样的运算符在编程中很方便,但在数学上下文中不是必需的。如果需要,可以根据其他术语进行定义: R?是 R |ε和 R + 是 RR * 。
†从数学上讲,即。形式语言理论中不存在诸如向后引用和向前/向后查找之类的功能。这些功能增加了正则表达式的数学定义中无法提供的附加表达能力。
答案 1 :(得分:1)
在某些传统的sed
实现中,您必须启用“扩展”正则表达式才能获得对+
表示“一个或多个”的支持。
有关这方面的证据,请参见:sed plus sign doesn't work