具有捕获组的有效正则表达式,但 sed 脚本不起作用

Posted

技术标签:

【中文标题】具有捕获组的有效正则表达式,但 sed 脚本不起作用【英文标题】:Valid RegEx with capture groups, but sed script not working 【发布时间】:2014-10-17 08:01:54 【问题描述】:

我有一个有效的 RegEx 模式,可以捕获三组字符串。我正在尝试在 sed 脚本中使用它来执行查找和替换操作,但我不断收到以下错误:

sed: -e expression #1, char 49: Unmatched ( or \(

我的脚本如下所示:

#!/usr/bin/env bash

pattern="^.*(require\(require\()(.+)(\);$)"
replace="require(\2;"
sed -i "s/$pattern/$replace/g" /usr/lib/node_modules/deployd/lib/type-loader.js

我正在尝试编辑的文件有一行显示:

var c = require(require('path').resolve(path) + '/node_modules/' + file);

...我想要的结果是:

var c = require('path').resolve(path) + '/node_modules/' + file;

我已经在这里确认了我的 RegEx:http://regex101.com/r/qO4jE5/1

...并在此处仔细检查:http://regexraptor.net/

知道我做错了什么吗?

【问题讨论】:

没有“有效的正则表达式”之类的东西。每个正则表达式仅在您将使用它的工具以及您在调用该工具时使用的选项和分隔符的上下文中“有效”。在 awk 中“有效”的正则表达式可能不在 sed 中,对于 sed 's/regexp//' “有效”的正则表达式可能不适用于 sed 's#regexp##'sed -r 's/regexp//',等等。 @EdMorton 我想如果你想分裂头发,我可以说“在 javascriptphp、Python 和 Bash 中实现所需结果的 RegEx 不适用于 sed”......但是对于为简洁起见,我认为在这里使用“有效”这个词是可以的。 :-) 如果您认为 RE 是“有效的”而不说明它对什么工具有效,甚至您是否认为它是“有效的”BRE、ERE、PerlRE 或 ...充其量是误导。您的 RE 包含 .+,例如,它在 sed 中表示任何单个字符后跟一个加号。这是任何 RE 的“有效”语法,但这是您想要的意思吗?在带有 -r 的 awk 或 GNU sed 中,它表示任何单个字符重复 1 次或多次。也许这就是你所说的那种“有效”? 【参考方案1】:

普通 sed 使用 BRE,基本正则表达式。在 BRE 中,捕获组 () 必须像这样 \(,\) 进行转义,并且要匹配文字 ) 符号,只需 ) 就足够了。

示例:

$ echo "var c = require(require('path').resolve(path) + '/node_modules/' + file);" | sed 's/^\(.*\)require(require\(.*\));$/\1require\2;/'
var c = require('path').resolve(path) + '/node_modules/' + file;

【讨论】:

太棒了,谢谢!我认为我写这个问题的时间比你回答它的时间要长。【参考方案2】:

如果你给它-r 标志,GNU sed 支持扩展正则表达式。

sed -i.bak -r 's/^(.*?require\()require\((.*)\)/\1\2/' file

Ideone Demo

【讨论】:

感谢您的回复!我接受了进来的第一个正确答案,但我真的很感激。 @ShaunScovil 不用担心。【参考方案3】:

你可以使用这个 sed:

sed -i.bak -r 's/^(.* )(require\(require\()(.+)(\);)$/\1require(\3;/' file
var c = require('path').resolve(path) + '/node_modules/' + file;

或者在 OSX 上使用 sed -E:

sed -i.bak -E 's/^(.* )(require\(require\()(.+)(\);)$/\1require(\3;/' file
var c = require('path').resolve(path) + '/node_modules/' + file;

【讨论】:

感谢您的快速回复! Avinash 打败了你,所以我接受了他的回答……但我也感谢你的帮助。

以上是关于具有捕获组的有效正则表达式,但 sed 脚本不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 `\d` 在 sed 的正则表达式中不起作用? [复制]

如何使用正则表达式仅捕获具有特定格式的有效句子的第一个单词? [复制]

具有不同量词的正则表达式捕获组

将排除捕获组的正则表达式

多行上的 sed 正则表达式无法捕获所有

Shell脚本 正则表达式 grep sed awk 工具