- 论坛徽章:
- 0
|
不贪婪的 sed
我注释的 ken 的 grep.c 中定义的正则表达式与 posix 标准有一些出入,毕竟是 1969 年 ken 搞 pdp7 unix 时候做的东西了,在 1979 年发行的 unix v7 中增加了 aho 的 egrep.y,介入了扩展正则表达式,称它为扩展,则 ken 的定义就只好叫基本正则表达式了,他的扩展主要是再次加入了 | 和 () 分别表示多选和组合,其中的 (...) 与 ken 的 \(...\) 的本质区别是 (...)* 表示子表达式的闭包,而\(...\)* 中的 * 是个普通字符, 就是说\(...\) 不起到组合作用。
在1979 年 unix v7 中引入的 sed 采用的是 ken 的正则表达式,这是必须的,因为作为编辑器,它需要后引用机制,aho 的定义不支持后引用,并且严肃的说后引用超出了纯粹的有穷自动机的表达能力。ken 定义中 \(...)\ 作用就是表示引用的开始和结束,以被后引用所引用。
经历了无休无止的功能扩展,新近的 sed 如 gnu sed 的\(...)\ 也起到了组合作用,比如
echo '333444' | sed 's/\(3\)*/<\1>/'
打印 <3>444
echo '333444' | sed 's/\(34*\)*/<\1>/'
打印 <3444>
这表明了后引用捕获的是与闭包中子表达式相匹配的最后的那个匹配串。
依据现存的发展和 posix 标准的明文。我增改了 ken 的 grep.c 。同时也就使 sed 的行为与标准相一致了。
我修订的 sed 的与 gnu sed 有一个明显的语义差别。
echo '333444' | ./sed 's/\(34\)*/<\1>/'
打印 33<34>44
而 gnu sed 中
echo '333444' | sed 's/\(34\)*/<\1>/'
打印 <>333444
期盼仁者指正。
我做的算法修订还需要严肃的调试和测试,不过我认为没有继续这种努力的必要。 |
|