我正在尝试格式化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();
上面的代码工作正常,但它没有将“content”拆分成自己的字符串,而是:
"<foo>", "<subfoo>", "<subsubfoo>", "content</subsubfoo>", "</subfoo>", "<subfoo/>", "</foo>"
有没有办法重写正则表达式来实现这一点,将不匹配分成他们自己的字符串?
或者,重新说明:在正则表达式匹配之前和之后是否可以分割字符串?
答案 0 :(得分:4)
使用此正则表达式(<.*?>)|(.+?(?=<|$))
并将匹配转换为List<string>
答案 1 :(得分:1)
XML不是常规语言(可以通过Pumping Lemma证明),因此无法使用正则表达式解析XML。
我建议你找一个好的XML库并使用它。
答案 2 :(得分:1)
您可以通过正则表达式或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;
}
它基本上抓住了它在文档中命中的第一个文本节点。 (除非您确定输入始终有效,否则您需要添加错误检查)
答案 3 :(得分:0)
由于忽略了html规范,<>
没有意义。
可以通过使用此(?<=>)|(?=<)
进行拆分来完成。
这会产生
<foo>
<subfoo>
<subsubfoo>
content
</subsubfoo>
</subfoo>
<subfoo/>
</foo>