我如何使用后缀来匹配单引号或双引号?
How can I use a look after to match either a single or a double quote?
我有一系列要提取的字符串:
hello.this_is("bla bla bla")
some random text
hello.this_is('hello hello')
other stuff
我需要得到的(从很多文件中,但这在这里并不重要)是hello.this_is(
和)
之间的内容,所以我想要的输出是:
bla bla bla
hello hello
如您所见,括号内的文本可以用双引号或单引号引起来。
如果这只是单引号,我会像这样使用后视和前视:
grep -Po "(?<=hello.this_is\(').*(?=')" file
# ^ ^
# returns ---> hello hello
同样,要从双引号中获取字符串,我会说:
grep -Po '(?<=hello.this_is\(").*(?=")' file
# ^ ^
# returns ---> bla bla bla
但是,我想匹配这两种情况,所以它同时获得单引号和双引号。我尝试使用 $''
进行转义,但无法成功:
grep -Po '(?<=hello.this_is\($'["\']').*(?=$'["\']')' file
# ^^^^^^^^ ^^^^^^^^
我当然可以用ASCII码说:
grep -Po '(?<=hello.this_is\([72]).*' file
但我想使用引号和单引号,因为 047
和 042
对我来说不像单引号和双引号那么具有代表性。
使用捕获组并查找其内容,如下所示:
grep -Po 'hello\.this_is\(([7"])((?!).|\.)*\)' file
这也关心转义字符,例如hello.this_is("bla b\"la bla")
如果输出应该是括号之间的内容,则同时使用 \K
和正前瞻:
grep -Po 'hello\.this_is\(([7"])\K((?!).|\.)*(?=\))' file
输出:
bla bla bla
hello hello
注意:此答案底部的 sed
命令仅在您的字符串表现得像
时才有效
"foo"
或
'bar'
一旦您的字符串开始出现异常 :) 如:
"hello \"world\""
它将不再有效。
您的输入看起来像源代码。对于稳定的解决方案,我建议使用该语言的解析器来提取字符串。
对于琐碎的用例:
您可以使用 sed
。该解决方案应该适用于任何 POSIX 平台,而 grep -oP
仅适用于 GNU grep:
sed -n 's/hello\.this_is(\(["'\'']\)\([^"]*\)\(["'\'']\).*//gp' file
# ^^^^^^^^ ^^
# capture group 2 ^
基于 revo 和 hek2mgl 的优秀答案,我最终使用了 grep
这样的:
grep -Po '(?<=hello\.this_is\((["'\''])).*(?=)' file
可以解释为:
grep
-Po
使用 Perl 正则表达式机器并只打印匹配项
'(?<=hello\.this_is\((["'\''])).*(?=)'
表达式
(?<=hello\.this_is\((["'\'']))
后视:搜索字符串前面有 "hello.this_is(",后面跟着 '
或 "
。另外,捕获最后一个字符以供稍后使用。
.*
匹配一切...
(?=)
直到捕获的字符(即'
或"
)再次出现。
这里的关键是使用["'\'']
来表示'
或"
。通过执行 '\''
,我们将关闭封闭表达式,填充文字 '
(我们必须转义)并再次打开封闭表达式。
我有一系列要提取的字符串:
hello.this_is("bla bla bla")
some random text
hello.this_is('hello hello')
other stuff
我需要得到的(从很多文件中,但这在这里并不重要)是hello.this_is(
和)
之间的内容,所以我想要的输出是:
bla bla bla
hello hello
如您所见,括号内的文本可以用双引号或单引号引起来。
如果这只是单引号,我会像这样使用后视和前视:
grep -Po "(?<=hello.this_is\(').*(?=')" file
# ^ ^
# returns ---> hello hello
同样,要从双引号中获取字符串,我会说:
grep -Po '(?<=hello.this_is\(").*(?=")' file
# ^ ^
# returns ---> bla bla bla
但是,我想匹配这两种情况,所以它同时获得单引号和双引号。我尝试使用 $''
进行转义,但无法成功:
grep -Po '(?<=hello.this_is\($'["\']').*(?=$'["\']')' file
# ^^^^^^^^ ^^^^^^^^
我当然可以用ASCII码说:
grep -Po '(?<=hello.this_is\([72]).*' file
但我想使用引号和单引号,因为 047
和 042
对我来说不像单引号和双引号那么具有代表性。
使用捕获组并查找其内容,如下所示:
grep -Po 'hello\.this_is\(([7"])((?!).|\.)*\)' file
这也关心转义字符,例如hello.this_is("bla b\"la bla")
如果输出应该是括号之间的内容,则同时使用 \K
和正前瞻:
grep -Po 'hello\.this_is\(([7"])\K((?!).|\.)*(?=\))' file
输出:
bla bla bla
hello hello
注意:此答案底部的 sed
命令仅在您的字符串表现得像
"foo"
或
'bar'
一旦您的字符串开始出现异常 :) 如:
"hello \"world\""
它将不再有效。
您的输入看起来像源代码。对于稳定的解决方案,我建议使用该语言的解析器来提取字符串。
对于琐碎的用例:
您可以使用 sed
。该解决方案应该适用于任何 POSIX 平台,而 grep -oP
仅适用于 GNU grep:
sed -n 's/hello\.this_is(\(["'\'']\)\([^"]*\)\(["'\'']\).*//gp' file
# ^^^^^^^^ ^^
# capture group 2 ^
基于 revo 和 hek2mgl 的优秀答案,我最终使用了 grep
这样的:
grep -Po '(?<=hello\.this_is\((["'\''])).*(?=)' file
可以解释为:
grep
-Po
使用 Perl 正则表达式机器并只打印匹配项'(?<=hello\.this_is\((["'\''])).*(?=)'
表达式(?<=hello\.this_is\((["'\'']))
后视:搜索字符串前面有 "hello.this_is(",后面跟着'
或"
。另外,捕获最后一个字符以供稍后使用。.*
匹配一切...(?=)
直到捕获的字符(即'
或"
)再次出现。
这里的关键是使用["'\'']
来表示'
或"
。通过执行 '\''
,我们将关闭封闭表达式,填充文字 '
(我们必须转义)并再次打开封闭表达式。