regex提取方括号下的数据,而忽略嵌套的括号



我有一个测试文件,其中的数据如下:

00:00:00 [3.7.1.1] : referer [query: *:*] [filter: []] [warn: false]
xyx [cyx] word word [data [idd] is] [new data [x:r]] dd
xyx [111] word word [22 [3]] [1 bbb [x3:r]] ff

我希望有一个如下的输出结果,即返回方括号下的所有数据,并将嵌套的括号视为字符串,并保留其间的空格:

[3.7.1.1] [query: *:*] [filter: []] [warn: false]
[cyx] [data [idd] is] [new data [x:r]]
[111] [22 [3]] [1 bbb [x3:r]]

为了实现这一点,我使用了以下语句,但它不起作用:

echo file.txt | sed 's/.*[([^]]*)].*/1/g'

但它只返回嵌套的结果。

[x:r]
[x3:r]

我在这里做错了什么?我是注册表达式的新手,所以任何帮助都会很有用。非常感谢。

sed不是处理嵌套平衡结构的最佳工具,但使用perl可以轻松做到这一点:

perl -pe 's/([(?:[^][]++|(?1))*])h?(*SKIP)(*F)|.//g' infile > outfile

请参阅regex演示。详细信息:

  • ([(?:[^][]++|(?1))*])h?(*SKIP)(*F)-在匹配的方括号和后面的可选水平空白之间匹配子字符串,并跳过匹配
  • |-或
  • .-匹配换行符以外的任何字符

在线观看演示:

s='00:00:00 [3.7.1.1] : referer [query: *:*] [filter: []] [warn: false]
xyx [cyx] word word [data [idd] is] [new data [x:r]] dd
xyx [111] word word [22 [3]] [1 bbb [x3:r]] ff'
perl -pe 's/([(?:[^][]++|(?1))*])h?(*SKIP)(*F)|.//g' <<< "$s"

输出:

[3.7.1.1] [query: *:*] [filter: []] [warn: false]
[cyx] [data [idd] is] [new data [x:r]] 
[111] [22 [3]] [1 bbb [x3:r]] 

与其尝试匹配括号外的所有内容并将其删除,不如尝试匹配括号内的所有内容,并仅返回这些内容(同样使用perl;递归正则表达式允许这种平衡对匹配(:

$ perl -nE 'say join " ", m/[(?:[^][]*|(?0))*]/g' input.txt
[3.7.1.1] [query: *:*] [filter: []] [warn: false]
[cyx] [data [idd] is] [new data [x:r]]
[111] [22 [3]] [1 bbb [x3:r]]

最新更新