正则表达式:在字符串中的两个标记之间拉出一个子字符串

时间:2008-08-04 13:47:11

标签: regex parsing

我有一个以下格式的文件:

Data Data
Data
[Start]
Data I want
[End]
Data

我想使用正则表达式从Data I want[Start]标记之间抓取[End]。谁能告诉我这是怎么做到的?

9 个答案:

答案 0 :(得分:63)

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

Zhich会将文本置于捕获中间。

答案 1 :(得分:23)

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

这有望放弃[start][end]标记。

答案 2 :(得分:5)

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

我有一段时间和类似的问题我可以告诉你这种方法有效......

答案 3 :(得分:4)

有关使用正则表达式查找匹配标记的缺陷的更完整讨论,请访问: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 "$1\n"'
 Data i want 

另一个技巧是使用 *?量词,关闭捕获的匹配的贪婪。例如,如果您有不匹配的 [end] 标记:

Data Data [Start] Data i want [End] Data [end]

你可能不想捕捉:

 Data i want [End] Data

答案 4 :(得分:4)

虽然您可以使用正则表达式来解析开始和结束标记之间的数据,但您需要仔细思考这是否是您想要关闭的路径。它的原因是标签嵌套的可能性:如果嵌套标签可能发生或可能发生,那么语言就不再是规则的,正则表达式不再是解析它的正确工具。

许多正则表达式实现(例如PCRE或perl的正则表达式)支持可用于实现此粗略效果的回溯。但PCRE(与perl不同)不支持无限制的回溯,一旦你有太多的标签,这实际上可能导致事情以奇怪的方式破坏。

有一篇非常常被引用的博客文章更多地讨论了这一点,http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html(google for it并检查当前的缓存,它们似乎有一些停机时间)

答案 5 :(得分:3)

好吧,如果你保证每个开始标记后跟一个结束标记,那么以下内容就可以了。

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

但是,如果您有复杂的文本,例如下面的内容:

[start] sometext [start] sometext2 [end] sometext [end]

然后你会遇到正则表达式的问题。

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

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

在上述情况下,我们可以保证不存在任何嵌套案例:

'<a></a>'

所以,这是一个复杂的问题,不能只用一个简单的答案来解决。

答案 6 :(得分: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
}

答案 7 :(得分:0)

请参阅此问题,在带有空格字符和点(.

的标记之间拉出文本

[\S\s]是我用的那个

Regex to match any character including new lines

答案 8 :(得分:0)

使用方括号[],[Start]和[End]读取文本,并使用值列表验证数组。 jsfiddle http://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;
}