我需要一个正则表达式才能找到所有'<'或'>'这不是xml标签。
示例:
<tag1>W<E><E</tag1>Z<>S
应该找到
<><<>
示例:
<tag1>W<E><E</E></tag1>Z<>S
应该找到
<<>
所以,任何点击'&lt;'或'&gt;'不是标签(是的,我们也有自我关闭标签,应该考虑到这一点)。
编辑#2: 我最终想做的是用html编码的值替换所有匹配。
编辑#3:
所以我想做的是从一个包含HTML的文本和一些额外的标签(很少有已知的标签)得到所有'&lt;'和'&gt;'这不包含在标签中。
示例(我想找到的粗体,所以我可以用它们的编码值替换它们):
<div>
<a href="link">Link with < characters</a>
<knownTag>Text with character ></knownTag>
<knownTag>Text < again ></knownTag>
<div>
结果应该是:
<div>
<a href="link">Link with < characters</a>
<knownTag>Text with character ></knownTag>
<knownTag>Text < again ></knownTag>
<div>
关于如何解决这个问题的任何想法?
答案 0 :(得分:6)
这可以用正则表达式来完成;但是,它并不像你建议的那么简单。您需要找到有效的标签并对其进行处理才能使其正常工作。我刚刚在编写一个快速且轻巧的xml / html解析器时就这样做了。该代码可在以下网址获得:
http://csharptest.net/browse/src/Library/Html/XmlLightParser.cs http://csharptest.net/browse/src/Library/Html/XmlLightInterfaces.cs
要使用解析器,您将从两个源文件的后面实现已定义的接口IXmlLightReader
。以下示例生成您想要的结果,并且还处理您未提及的其他几个功能,如CDATA部分,处理指令,DTD等。
class RegexForBadXml
{
const string Input = "<?xml version=\"1.0\"?>\r\n<div>\r\n\t<a href=\"link\">Link with < characters</a>\r\n\t<knownTag>Text with character > &and other &#BAD; stuff</knownTag>\r\n\t<knownTag>Text < again ></knownTag>\r\n\t<knownTag><![CDATA[ Text < again > ]]></knownTag>\r\n<div>";
private static void Main()
{
var output = new StringWriter();
XmlLightParser.Parse(Input, XmlLightParser.AttributeFormat.Html, new OutputFormatter(output));
Console.WriteLine(output.ToString());
}
private class OutputFormatter : IXmlLightReader
{
private readonly TextWriter _output;
public OutputFormatter(TextWriter output)
{
_output = output;
}
void IXmlLightReader.StartDocument() { }
void IXmlLightReader.EndDocument() { }
public void StartTag(XmlTagInfo tag)
{
_output.Write(tag.UnparsedTag);
}
public void EndTag(XmlTagInfo tag)
{
_output.Write(tag.UnparsedTag);
}
public void AddText(string content)
{
_output.Write(HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(content)));
}
public void AddComment(string comment)
{
_output.Write(comment);
}
public void AddCData(string cdata)
{
_output.Write(cdata);
}
public void AddControl(string cdata)
{
_output.Write(cdata);
}
public void AddInstruction(string instruction)
{
_output.Write(instruction);
}
}
}
前面的程序输出以下结果:
<?xml version="1.0"?>
<div>
<a href="link">Link with < characters</a>
<knownTag>Text with character > &and other &BAD; stuff</knownTag>
<knownTag>Text < again ></knownTag>
<knownTag><![CDATA[ Text < again > ]]></knownTag>
<div>
注意:我添加了xml声明,CDATA和'&amp;'仅供测试的文字。
答案 1 :(得分:3)
使用This question中的方法之一并删除输入的 然后string output = new string(input.ToCharArray().Where(c=> c=='<'||c=='>').ToArray());
答案 2 :(得分:2)
从您的示例来看,似乎您不是像主题建议的那样搜索XML文件,而是类似XML的文件 - 如果它们不包含“&lt;”,则可能是XML文件。和“&gt;”你正在寻找的人物。
但是你还没有明确指出任务。应该怎么做,例如,
<tag1>xxxx</tag2>
或
<tag1><x a="</tag1>"/></tag1>
单独使用正则表达式来完成第二种情况非常困难(也许是不可能的)。您需要定义要接受的语法或输入语言(XML的扩展)并使用递归解析技术对其进行解析。
答案 3 :(得分:0)
在您的有限情况下,似乎有一种可能有效的算法策略,可以概述如下:
<something>
。 </something>
<
和>
。答案 4 :(得分:0)
我对您的问题并不太了解,但我编写了一个代码,该代码采用您的HTML示例并返回与您预期的HTML结果相同的HTML结果。
MatchCollection matches = Regex.Matches(YourHTML, @"(?<=<.*?>).+(?=<.*?>)");
foreach (Match match in matches)
{
YourHTML = YourHTML.Replace(match.Value, HttpUtility.HtmlEncode(match.Value));
}
答案 5 :(得分:0)
鉴于编辑#3中你的问题的新表述,我认为你可以使用匹配“&lt;”的正则表达式解决它接下来是负向前瞻
<(?!(/?(a|b|div|p|....|!--|!\[CDATA\[))
匹配<
(如果之后没有其中一个已知的标记名称),然后将此"<"
替换为"<"
答案 6 :(得分:0)
static string test(string input)
{
var r = @"(<(.*?)>)(.*?)</\2>";
while (Regex.IsMatch(input, r))
input = Regex.Replace(input, r, "$3");
return Regex.Replace(input, @"\w", "");
}