正则表达式:从字符串中提取两个标记之间的子字符串

48

我有一个文件,其格式如下:

数据 数据
数据
[开始]
我想要的数据
[结束]
数据

我想使用正则表达式从[开始][结束]标记之间提取我想要的数据。 请问有人能告诉我如何实现吗?


1
与“RegEx获取标签内文本”的方法类似--http://stackoverflow.com/questions/353309/regex-to-get-text-within-tags - Robin Rodricks
9个回答

63
\[start\](.*?)\[end\]

这将在截取内部将文本置于中间。


6
这仍然无法捕获带有换行符的字符串。 - Doug
2
@Doug 使用选项 dotall。这不是正则表达式的问题。 - AlexR

23
\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]

希望这能成功删除 [start][end] 标记。


2
前瞻可能不太高效,但我喜欢你如何防止它在出现意外的 [start][end] 时崩溃。 总是考虑边缘情况并预先处理它们是很好的。 - Alex W

5
$text ="Data Data Data start Data i want end Data";
($content) = $text =~ m/ start (.*) end /;
print $content;

我曾经有过类似的问题,而且我可以告诉你这种方法是有效的...


4
使用正则表达式来查找匹配的标签可能会遇到一些问题,关于这些问题的更详细讨论可以在如何找到匹配/嵌套的内容?中找到。特别需要注意的是,为了正确解释嵌套标签,实际上需要一个完整的解析器。
请注意,为了回答所提出的问题,需要关闭大小写敏感性。在Perl中,可以通过添加i修饰符来实现。
$ echo "Data Data Data [Start] Data i want [End] Data" \
  | perl -ne '/\[start\](.*?)\[end\]/i; print "$1\n"'
 Data i want 

另一个技巧是使用?量词,它可以关闭捕获匹配的贪婪性。例如,如果你有一个不匹配的[end]标签:
Data Data [Start] Data i want [End] Data [end]

你可能不想捕捉:
 Data i want [End] Data

4
虽然您可以使用正则表达式来解析在开放和关闭标签之间的数据,但是您需要认真考虑是否要走这条路。原因是标签可能嵌套:如果嵌套标签可能发生或可能发生,则该语言被认为不再是常规的,而正则表达式停止成为解析它的正确工具。
许多正则表达式实现(例如PCRE或perl的正则表达式)支持回溯,可以用于实现此粗略效果。但是PCRE(与perl不同)不支持无限回溯,并且一旦有太多标签,这实际上会导致事情出现奇怪的故障。
有一篇非常常见的博客文章更详细地讨论了这一点,请参见http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html(搜索谷歌并检查当前缓存,他们似乎正在经历一些停机时间)。

3

如果您保证每个开始标记都有一个结束标记,那么以下方法可以实现。

\[start\](.*?)\[end\]

然而,如果您有以下复杂的文本:
[start] sometext [start] sometext2 [end] sometext [end]

如果你使用正则表达式,可能会遇到问题。

现在,以下示例将提取页面中的所有热门链接:

'/<a(.*?)a>/i'

在上述情况下,我们可以保证不会出现任何嵌套的情况:
'<a></a>'

因此,这是一个复杂的问题,不能仅仅用简单的答案来解决。


1

使用Perl,您可以用()将所需数据括起来,稍后再提取出来,其他语言可能也有类似的功能。

if ($s_output =~ /(data data data data START(data data data)END (data data)/) 
{
    $dataAllOfIt = $1;      # 1 full string
    $dataInMiddle = $2;     # 2 Middle Data
    $dataAtEnd = $3;        # 3 End Data
}

0

读取方括号[]中的文本,例如[Start]和[End],并使用值列表验证数组。jsfiddlehttp://jsfiddle.net/muralinarisetty/r4s4wxj4/1/

var mergeFields = ["[sitename]",
                   "[daystoholdquote]",
                   "[expires]",
                   "[firstname]",
                   "[lastname]",
                   "[sitephonenumber]",
                   "[hoh_firstname]",
                   "[hoh_lastname]"];       

var str = "fee [sitename] [firstname] \
sdfasd [lastname] ";
var res = validateMeargeFileds(str);
console.log(res);

function validateMeargeFileds(input) {
    var re = /\[\w+]/ig;
    var isValid;
    var myArray = input.match(re);

    try{
        if (myArray.length > 0) {
            myArray.forEach(function (field) {

                isValid = isMergeField(field);

                if (!isValid){
                   throw e;                        
                }
            });
        }
    }
    catch(e) {        
    }

    return isValid;
}

function isMergeField(mergefield) {
    return mergeFields.indexOf(mergefield.toLowerCase()) > -1;
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接