正则表达式:在字符串中的两个标签之间提取子字符串
我有以下格式的文件:
Data Data Data [Start] Data I want [End] Data
我想使用Regex从[Start]
和[End]
标记之间获取"我想要的数据"。谁能告诉我该怎么做?
解决方案
回答
\[start\](.*?)\[end\]
Zhich'll将文本放在捕获的中间。
回答
\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]
希望这也会删除[start]
和[end]
标记。
回答
使用Perl,我们可以用()包围所需的数据,并在以后将其拉出,也许其他语言也具有类似的功能。
if ($s_output =~ /(data data data data START(data data data)END (data data)/) { $dataAllOfIt = ; # 1 full string $dataInMiddle = ; # 2 Middle Data $dataAtEnd = ; # 3 End Data }
回答
有关使用正则表达式查找匹配标签的陷阱的更完整讨论,请参见:http://faq.perl.org/perlfaq4.html#How_do_I_find_matchi。特别要注意的是,嵌套标签确实需要完整的解析器才能正确解释。
请注意,为了回答上述问题,必须关闭区分大小写的功能。在perl中,这是i修饰符:
$ echo "Data Data Data [Start] Data i want [End] Data" \ | perl -ne '/\[start\](.*?)\[end\]/i; print "\n"' Data i want
另一个技巧是使用*?量词可关闭捕获的匹配的贪婪性。例如,如果我们有一个不匹配的[end]标签:
Data Data [Start] Data i want [End] Data [end]
我们可能不想捕获:
Data i want [End] Data
回答
尽管我们可以使用正则表达式来解析打开标签和结束标签之间的数据,但是我们需要认真思考一下这是否是我们想走的一条路。造成这种情况的原因是标签可能会嵌套:如果嵌套标签可能发生或者可能曾经发生,则据说该语言不再是正则语言,而正则表达式不再是解析它的合适工具。
许多正则表达式实现(例如PCRE或者perl的正则表达式)都支持回溯,可用于实现这种粗糙效果。但是PCRE(与perl不同)不支持无限的回溯,而实际上,一旦标签太多,它就会以奇怪的方式破坏事物。
http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html(谷歌需要它,目前正在检查缓存,他们似乎有一些停机时间),这是一篇非常常用的博客文章,对此进行了更多讨论。
回答
好吧,如果我们保证每个开始标记后面都有一个结束标记,那么下面的方法将起作用。
\[start\](.*?)\[end\]
但是,如果我们有复杂的文字,例如以下内容:
[start] sometext [start] sometext2 [end] sometext [end]
那么我们会遇到正则表达式的问题。
现在,以下示例将提取页面中的所有热链接:
'/<a(.*?)a>/i'
在上述情况下,我们可以保证不会出现以下任何嵌套情况:
'<a></a>'
因此,这是一个复杂的问题,不能仅仅通过简单的答案来解决。