如何在GREP,REGEX或PERL模式下提取string
我有一个这样的文件:
<table name="content_analyzer" primary-key="id"> <type="global" /> </table> <table name="content_analyzer2" primary-key="id"> <type="global" /> </table> <table name="content_analyzer_items" primary-key="id"> <type="global" /> </table>
我需要提取“name =”后面的引号,即content_analyzer,content_analyzer2和content_analyzer_items。
我在一个Linux机器上这样做,所以使用sed,perl,grep或bash的解决scheme是好的。
由于您需要匹配内容而不将其包含在结果中(必须与name="
匹配name="
但不是所需结果的一部分),因此需要采用某种forms的零宽度匹配或组捕获,可以使用以下工具轻松完成此操作:
Perl的
使用Perl,您可以使用n
选项逐行循环,并打印捕获组的内容(如果匹配):
perl -ne 'print "$1\n" if /name="(.*?)"/' filename
GNU grep
如果你有一个改进的grep版本,例如GNU grep,你可以使用-P
选项。 这个选项将启用类似于Perl的正则expression式,允许您使用\K
这是一个简写的后台。 它将重置匹配位置,所以任何之前它是零宽度。
grep -Po 'name="\K.*?(?=")' filename
o
选项使grep仅打印匹配的文本,而不是整行。
Vim – 文本编辑器
另一种方法是直接使用文本编辑器。 使用Vim,完成这个的各种方法之一是删除没有name=
,然后从结果行中提取内容:
:v/name=/d :%s/\v.*name\="([^"]+)".*/\1
标准grep
如果您无法访问这些工具,出于某种原因,使用标准的grep可以实现类似的function。 但是,如果没有环视,以后需要进行一些清理:
grep -o 'name="[^"]*"' filename
关于保存结果的说明
在上面的所有命令中,结果都将被发送到stdout
。 重要的是要记住,您可以随时通过以下方式将其保存到文件中:
> result
到命令的末尾。
如果您使用Perl,请下载一个模块来parsingXML: XML :: Simple , XML :: Twig或XML :: LibXML 。 不要重新发明轮子。
正则expression式是:
.+name="([^"]+)"
那么分组就会在\ 1
一个HTMLparsing器应该用于这个目的而不是正则expression式。 一个使用HTML::TreeBuilder
Perl程序:
程序
#!/usr/bin/env perl use strict; use warnings; use HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new_from_file( \*DATA ); my @elements = $tree->look_down( sub { defined $_[0]->attr('name') } ); for (@elements) { print $_->attr('name'), "\n"; } __DATA__ <table name="content_analyzer" primary-key="id"> <type="global" /> </table> <table name="content_analyzer2" primary-key="id"> <type="global" /> </table> <table name="content_analyzer_items" primary-key="id"> <type="global" /> </table>
产量
content_analyzer content_analyzer2 content_analyzer_items
这可以做到这一点:
perl -ne 'if(m/name="(.*?)"/){ print $1 . "\n"; }'
这是一个使用HTML tidy&xmlstarlet的解决scheme:
htmlstr=' <table name="content_analyzer" primary-key="id"> <type="global" /> </table> <table name="content_analyzer2" primary-key="id"> <type="global" /> </table> <table name="content_analyzer_items" primary-key="id"> <type="global" /> </table> ' echo "$htmlstr" | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null | sed '/type="global"/d' | xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n
糟糕,sed命令当然要在整理命令之前:
echo "$htmlstr" | sed '/type="global"/d' | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null | xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n