代码之家  ›  专栏  ›  技术社区  ›  Phobis

如何编写正则表达式来匹配没有子元素的XML元素的任何非空内容?

  •  -1
  • Phobis  · 技术社区  · 15 年前

    以这个XML为例:

    <1>
        <2><3 /></2>
        <4>
            <5>This is match 1</5>
        </4>
        <6>     
             </6>
        <7>    &nbsp;&nbsp;&nbsp;&nbsp;    &nbsp;&nbsp;&nbsp;</7>
        <8>This is match 2</8>
    </1>
    

    所以只有元素5和8匹配。其余元素有子元素或“空白” (空格、制表符、回车、新行和;ampnbsp;)

    “一般来说,您不能使用正则表达式解析XML。

    它是无效的XML 所以我需要这样做才能使它有效。然后我可以将其视为xml:)

    换句话说,它是一个非常类似XML的字符串。

      Regex ElementExpression = new Regex(
          @"<(?'tag'\w+?).*>" + // match first tag, and name it 'tag'
          @"(?'text'[^<>]*[\\S]+?)" + // match text content, name it 'text'
          @"</\k'tag'>" // match last tag, denoted by 'tag'
          , RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
    
    6 回复  |  直到 15 年前
        1
  •  2
  •   Community Daniel Roseman    7 年前

    一般来说 you must not parse XML using regular expressions .

    相反,使用 System.Xml 命名空间。

        2
  •  1
  •   GrayWizardx    15 年前

    这方面的正则表达式将相当麻烦。基本上你需要一个寻找平衡对的正则表达式 LinK

    <(?<tag>\w*)>(?<text>.*)</\k<tag>> 
    

    (由 Expresso )

    (?<text>.*) <- is what you will have to construct by hand to match your elim criteria
    
        3
  •  1
  •   Josh Stodola    15 年前

    我不会用正则表达式来做这个!我将通过一个整洁的实用程序运行它,然后使用XSLT和XPath。

        4
  •  0
  •   Phobis    15 年前

    通过使用一个正则表达式获取元素,使用第二个正则表达式删除带有我定义的空格的元素,我可以得到我想要的。

      Regex ElementExpression = new Regex(
                @"<(?'tag'\w+?)(?'attributes'.*?)>" + // match first tag, and name it 'tag'
                @"(?'text'[^<>]*?)" + // match text content, name it 'text'
                @"</\k'tag'>" // match last tag, denoted by 'tag'
                , RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
    
    
      Regex WhiteSpaceExpression = new Regex(@"\A((&nbsp;)|(\s)|(\r))*\Z", RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
    
      text = ElementExpression.Replace(text, delegate(Match match){
            if (match.Groups.Count > 0){
               Group textGroup = match.Groups["text"];
               if (!WhiteSpaceExpression.IsMatch(textGroup.Value)){
                  return String.Format("<{0}{1}>{2}</{0}>", match.Groups["tag"].Value, match.Groups["attributes"].Value, HttpUtility.HtmlEncode(textGroup.Value));
               }
               else{
                  return String.Format("<{0}{1} />", match.Groups["tag"].Value, match.Groups["attributes"].Value);
               }
            }
            return match.Value;
      });
    
        5
  •  0
  •   Robert Rossney    15 年前

    如果不是XML,那就糟糕了。说它是一个“紧密代表XML的字符串”并不是一个恰当的问题定义。字符串与XML非常相似的方式有很多种,为一种方式设计的解析解决方案无法与另一种方式协同工作。

    如果您可以明确说明字符串偏离XML的方式,也就是说,如果您可以确定原始开发人员在尝试编写XML时犯的具体错误,那么应该可以消除这种损害,将字符串转换为格式良好的XML,然后使用DOM方法查找您要查找的数据。

    如果你 不能 如果要具体说明字符串偏离XML的方式,那么您将面临比编写正则表达式更大的问题。

        6
  •  -1
  •   zen    15 年前

    第一关。提取所有字符串。

    my @strings = $s =~ /<[^>]+>([^<>]+)<[^/>]*/[^/>]*>/g;
    

    @strings = grep {!/&nbsp;|^\s+$/} @strings;