我一直在创建一个自定义标记解析器,以便在我的应用程序中使用。 除非打开和关闭标签位于不同的行上,否则它可以完美运行。
示例:
<test>This is a test</test>
完美无缺,但
<test>
this
is
a
test
</test>
返回一个空白字符串。
我目前的解决方法是使用[-n]
作为字符串中的换行符,并以编程方式将其替换为\n\r
。然而,这非常不方便。
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace AsysEditor.Classes
{
/// <summary>
/// Contains the methods needed to parse a simple XML file
/// </summary>
class XMLParser
{
/// <summary>
/// Parses a simple XML file.
/// </summary>
/// <remarks>
/// Does NOT support nested tags.
/// </remarks>
/// <param name="xml">The file to parse</param>
/// <param name="tag">The wanted value</param>
/// <param name="clean">Remove whitespace</param>
/// <param name="replaceNewLines">Replace "[-n]" with "\n\r"</param>
/// <returns></returns>
public static string Parse(string xml, string tag, bool clean, bool replaceNewLines)
{
if (xml == String.Empty || tag == String.Empty) { return "error"; }
if (!(xml.Contains("<" + tag + ">"))) { return "error"; }
// Get all XML tags: <tag>
string _tag = "\\<(.*?)\\>";
MatchCollection tagMatches = new Regex(_tag).Matches(xml);
List<string> tags = new List<string>();
// Add the tag to a list
foreach (Match m in tagMatches)
{
// Clean the tag and add it to the list
tags.Add(m.Groups[1].Value.Replace("<", string.Empty).Replace(">", string.Empty));
}
// Get the value of the tag
foreach (string h in tags)
{
if (!h.Equals(tag)) continue;
string head = "\\<" + h + "\\>";
string foot = "\\</" + h + "\\>";
string contents = new Regex(head + "(.*?)" + foot).Match(xml).Groups[1].Value;
// Clean the result if nessesary
if (clean) return contents.Trim();
else if (replaceNewLines) return contents = Regex.Replace(contents, "\\[-n\\]", "\r\n");
else return contents;
}
return "error";
}
}
}
(如果它做了很多不必要的事情,那是因为我以后会扩展功能)
如果有人可以在这里解释我的错误,那将会非常有帮助。
答案 0 :(得分:2)
我已将其分解为最简单的形式,即只匹配您要查询的标签内的文字。
以下是示例代码:
const string TAG_REGEX_PATTERN = @"(?:<{0}>)([^<]+?)(?:<\/{0}>)";
public static string Parse(string xml, string tag, bool clean, bool replaceNewLines)
{
if (xml == String.Empty || tag == String.Empty) { return "error"; }
MatchCollection tagMatches = new Regex(string.Format(TAG_REGEX_PATTERN, tag), RegexOptions.Multiline | RegexOptions.IgnoreCase).Matches(xml);
IList<string> tags = new List<string>();
// Add the tag to a list
foreach (Match m in tagMatches)
{
// Add the tag to the list
tags.Add(m.Groups[1].Value);
break; //break as only interested in first result.
}
string result = tags.Count == 0 ? null : tags[0];
if (!string.IsNullOrWhiteSpace(result))
{
if (clean)
result = result.Trim();
if (replaceNewLines)
result = result.Replace("\r\n", " ");
}
else
result = "error";
return result;
}
现在,这将匹配您要查找的标记内的文本,并忽略实际标记。
使用相关标签(使用string.Format()
)直接格式化正则表达式,并在下面生成正则表达式。
(?:<test>)([^<]+?)(?:<\/test>)
现在我已经将循环留在那里,以防你希望返回所有标签的值。
答案 1 :(得分:1)
RegEx是面向行的。
由于您已经拥有适用于单行输入的内容,请考虑清理输入:
public static string Parse(string xml, string tag, bool clean, bool replaceNewLines)
{
xml = xml.Replace("\r", "").Replace("\n", " ");
...
}