Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 考虑特殊正则表达式如何正确使用sed replacement命令的back引用_Regex_Linux_Sed_Regular Language_Backreference - Fatal编程技术网

Regex 考虑特殊正则表达式如何正确使用sed replacement命令的back引用

Regex 考虑特殊正则表达式如何正确使用sed replacement命令的back引用,regex,linux,sed,regular-language,backreference,Regex,Linux,Sed,Regular Language,Backreference,我正在学习linux上的sed s/regexp/replacement/command 这里有一些来自phone.txt的号码 (555)555-1212 (555)555-1213 (555)555-1214 (666)555-1215 (777)555-1217 我想使用正则表达式(我已经测试过了) 匹配以(555)开头的数字。然后我想要这些匹配数字的三部分的输出,如下所示:(数字(555)555-1212的一个例子) 我尝试了以下命令: cat phone.txt | sed 's/\

我正在学习linux上的sed s/regexp/replacement/command

这里有一些来自phone.txt的号码

(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(777)555-1217
我想使用正则表达式(我已经测试过了)

匹配以(555)开头的数字。然后我想要这些匹配数字的三部分的输出,如下所示:(数字(555)555-1212的一个例子)

我尝试了以下命令:

cat phone.txt | sed 's/\(\\\(555\\\)\)\(.*-\)\(.*$)/Area code: \1 Second: \2 Third: \3/'
但系统给了我:

sed: -e expression #1, char 66: Unmatched ( or \(
所有号码的总指挥是:

cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area code: \1 Second: \2 Third: \3/'
资料来源:

但我只想对以(555)开头的数字执行sed,并通过反向引用将其添加到输出中


您能告诉我如何正确地编写这个特殊命令吗?

Ypu在您的
sed
命令中使用POSIX BRE语法,在这种模式中,未转义的括号与文字括号匹配。此处的转义括号定义了捕获组

你可以用

sed -E 's/(\(555\))(.*-)(.*)/Area code: \1 Second: \2 Third: \3/'


POSIX ERE语法中的文字括号(使用
-E
选项启用)会像在所有常见的在线正则表达式测试程序中一样进行转义,未转义的括号定义捕获组。

您可以使用字符串中包含的格式来概括,以选择第一个
555
,第二个
555
和第三个
1212
,但不限于
s/find/replace/
替换形式的
sed
中的任何特定前缀。然后,您可以根据需要进行限制,在替换之前包括一个匹配条件,在其中输入您的
555
666

要将模式匹配与替换一起包含,请使用以下形式:

sed '/pattern/s/find/replace/'
要使模式匹配抑制除与模式匹配的行之外的所有行的输出,您需要传递
-n
选项以抑制模式空间的打印,并在替换表单的末尾包含
p
,以显式打印匹配的行,例如

sed -n '/pattern/s/find/replace/p'
现在,让我们来看看你手头的问题。要将重新格式化的输出限制为仅以
(555)
开头的行,请执行以下操作:

$ sed -n '/^(555)/s/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/p' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
注意:反向引用仅捕获数字,而不捕获
(..)
'-'

要重新格式化所有行,您需要删除
-n
/pattern/
以及最后的
p
,只使用基本
sed的/find/replace/
表单,例如

$ sed 's/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (777) Second: 555- Third: 1217

请仔细查看,如果您还有其他问题,请告诉我。

您可以使用
sed-E/(\(555\)(.-(.-)(.*)/区号:\1秒:\2秒:\3/'
。使用POSIX ERE语法,您可以像在所有常见的在线正则表达式测试程序中一样转义括号。当您使用BRE时,您不必双重转义
)来获得文字括号;只需单独使用括号,因此
而不是
\\\\(
。谢谢,这是我想知道的一点。向sed提供-E或-r或--regexp extended以启用扩展正则表达式语法非常重要。感谢您的详细回答。因此正则表达式
^(\([^)]*\)\([^-]*\)-\(.\\)$
是POSIX BRE语法,转义括号定义了捕获组(感谢@wiktor stribiżew的回答)。我说的对吗?是的,你100%正确。如果有合理的方式形成正则表达式,我更喜欢BRE。谢谢。我想接受你的回答,但@wiktor stribiżew的回答告诉了我我想知道的问题。你的回答也很有效。没问题,完全取决于你。很高兴能提供帮助。
$ sed -n '/^(555)/s/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/p' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
$ sed 's/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (777) Second: 555- Third: 1217