这是我之前问题的后续“sed 仅打印该行的第一个模式匹配”
我正在处理的数据
... "one" ... "two" ... "three" ...
我想one
被打印出来,我接受的答案是这样的
sed 's/[^"]*"\([^"]*\)".*/\1/'
我搜索并试图理解这个正则表达式,但我无法理解这个正则表达式。
我的理解是:
[^"]
表示不匹配"
*
表示匹配 0 前面的任意数量的字符*
\(
和\)
意味着存储它们之间匹配的任何内容,以便稍后通过相应的数字引用,即在我们的例子中它只是\1
.*
是贪婪的,意味着任意数量的字符
我不明白[^"]*
这里的意思。
我如何口头阅读整个正则表达式以便我理解这里发生了什么
sed 's/[^"]*"\([^"]*\)".*/\1/'
答案1
NODE EXPLANATION
--------------------------------------------------------------------------------
[^"]* any character except: '"' (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
" '"'
--------------------------------------------------------------------------------
\( group and capture to \1:
--------------------------------------------------------------------------------
[^"]* any character except: '"' (0 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
\) end of \1
--------------------------------------------------------------------------------
" '"'
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
sed
该命令的第二个部分调用\1
使用括号中“捕获”的内容。应该注意的是,整个sed
命令本身并不是正则表达式。在构造中s/needle/pin/g
,正则表达式是needle
or,如果您喜欢“包装”正则表达式(例如用于awk
),/needle/
则 。
答案2
由于[^"]*
表示“不是引号的任意数量的字符”,并且由于sed
正则表达式是贪婪的,[^"]*
因此确保后面的引号是字符串中的第一个引号。第二个类似的正则表达式确保后面的引号是字符串中的第二个引号。.*
与第二个引用后面的内容匹配。
因此[^"]*"\([^"]*\)".*
意味着“匹配整行并将第二个引号分隔的字段放入\1
”中。