2

我正在尝试格式化 XML 文档,所以我将一个字符串传递给一个方法,例如:

"<foo><subfoo><subsubfoo>content</subsubfoo></subfoo><subfoo/></foo>"

我正在尝试根据找到标签来拆分它。我想将每个元素(标签或内容)拆分为一个唯一的字符串,例如:

"<foo>", "<subfoo>", "<subsubfoo>", "content", "</subsubfoo>", "</subfoo>", "<subfoo/>", "</foo>"

为此,我使用以下代码:

string findTagString = "(?<=<.*?>)";
Regex findTag = new Regex(findTagString);
List<string> textList = findTag.Split(text).ToList();

上面的代码工作正常,除了它没有将“内容”拆分成自己的字符串,而是:

"<foo>", "<subfoo>", "<subsubfoo>", "content</subsubfoo>", "</subfoo>", "<subfoo/>", "</foo>"

有没有办法重写正则表达式来完成这一点,将不匹配项拆分成自己的字符串?

或者,改写:是否可以在正则表达式匹配之前和之后拆分字符串?

4

4 回答 4

4

使用此正则表达式(<.*?>)|(.+?(?=<|$)) 并将匹配项转换为List<string>

于 2012-07-10T18:48:14.440 回答
2

由于忽略了 html 规范,<>因此没有任何意义。

可以简单地通过拆分来完成 this (?<=>)|(?=<)

这产生

<foo>
<subfoo>
<subsubfoo>
content
</subsubfoo>
</subfoo>
<subfoo/>
</foo>
于 2012-07-10T20:03:15.483 回答
1

XML 不是正则语言(可以用 Pumping Lemma 证明),因此 XML 不能用正则表达式解析。

我建议你找到一个好的 XML 库并使用它。

于 2012-07-10T18:51:41.043 回答
1

您可以通过 regex 或 xpath 执行此操作,具体取决于 xml 的复杂性。

如果你想使用正则表达式,你可能想做这样的事情:

public static string xml = "<foo><subfoo><subsubfoo>content</subsubfoo></subfoo><subfoo/></foo>";
public static Regex re = new Regex(@"\<([A-Za-z0-9]*)\b[^>]*\>(.*?)\</\1\>");

static string GetContentViaRegex()
{
    string content = xml;
    while (re.IsMatch(content))
    {
        Match match = re.Match(content);
        if (!match.Success)
            break;

        content = match.Groups[2].Value;
    }
    return content;
}

正则表达式基本上搜索匹配的开始/结束标签(你不想匹配类似的东西<foo>stuff here, possibly including more tags</bar>),并且你不断钻研匹配的标签,直到你找到最里面的内容。此正则表达式假定任何标签上都没有属性。

如果您想通过 xpath 执行此操作,您可以执行以下操作:

static string GetContentViaXPath()
{
    var nav = new XPathDocument(new StringReader(xml)).CreateNavigator();
    return nav.SelectSingleNode("//text()").Value;
}

它基本上抓住了它在文档中命中的第一个文本节点。(除非您确定输入始终有效,否则您需要添加错误检查)

于 2012-07-10T19:05:40.423 回答