【问题标题】:Regex: To pull out a sub-string between two tags in a string正则表达式:提取字符串中两个标签之间的子字符串
【发布时间】:2010-09-05 07:11:57
【问题描述】:

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

资料资料 数据 [开始] 我要的数据 [结尾] 数据

我想使用正则表达式从[Start][End] 标记之间获取Data I want。谁能告诉我如何做到这一点?

【问题讨论】:

标签: regex parsing


【解决方案1】:
\[start\](.*?)\[end\]

Zhich 会将文本放在捕获的中间。

【讨论】:

  • 这仍然不会捕获有换行符的字符串
  • @Doug 使用选项 dotall。不是正则表达式的问题。
【解决方案2】:
\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]

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

【讨论】:

  • 向前看可能效率较低,但如果出现意外的[start][end],我喜欢你如何防止它中断。考虑边缘情况并抢占它们总是好的。
【解决方案3】:

读取方括号 [] 中的文本,即 [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;
}

【讨论】:

    【解决方案4】:

    参考这个问题提取带有空格字符和点的标签之间的文本(.

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

    Regex to match any character including new lines

    【讨论】:

      【解决方案5】:
      $text ="Data Data Data start Data i want end Data";
      ($content) = $text =~ m/ start (.*) end /;
      print $content;
      

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

      【讨论】:

        【解决方案6】:

        好吧,如果你保证每个开始标签后面都有一个结束标签,那么下面的方法就可以了。

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

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

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

        那么你会遇到正则表达式的问题。

        现在下面的例子将拉出页面中的所有热链接:

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

        在上述情况下,我们可以保证不会有任何嵌套的情况:

        '<a></a>'
        

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

        【讨论】:

          【解决方案7】:

          使用 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
          }
          

          【讨论】:

            【解决方案8】:

            虽然您可以使用正则表达式来解析开始标签和结束标签之间的数据,但您需要仔细考虑这是否是您想要走的路径。其原因是标签嵌套的潜力:如果嵌套标签可能发生或可能发生,则称该语言不再是正​​则语言,正则表达式不再是解析它的适当工具。

            很多正则表达式的实现,比如PCRE或者perl的正则表达式,都支持回溯,可以用来实现这种粗略的效果。但是 PCRE(与 perl 不同)不支持无限回溯,一旦标签太多,这实际上会导致事情以奇怪的方式中断。

            有一篇非常常被引用的博客文章对此进行了更多讨论,http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html(谷歌搜索它并检查当前缓存,他们似乎有一些停机时间)

            【讨论】:

              【解决方案9】:

              有关使用正则表达式查找匹配标签的陷阱的更完整讨论可以在以下位置找到: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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-05-30
                • 2014-06-12
                • 2017-04-15
                • 1970-01-01
                相关资源
                最近更新 更多