用C#中的其他标记替换具有属性的html标记
本文关键字:属性 替换 html 标记 其他 | 更新日期: 2023-09-27 17:58:22
基本上,我想用其他标签替换html标签,例如:
</br> --> <LineBreak/>
<p> --> <Paragraph>
一开始,我使用
convertedHtml = html.replace("</br>","<LineBreak/>");
这个方法的问题是需要管理所有的案例,我想要一个泛型类。例如,这种方法不可能与以下标签内容:
<p class="foo"> --> <Paragraph>
<p id="bar"> --> <Paragraph>
.....
我该如何解决此问题?
edit:注意,我事先不知道标签中有哪些属性。我想替换包含"p"、"/p"、"br"、"b"、…的标记。。。
也许您可以使用HTML敏捷包(http://htmlagilitypack.codeplex.com/)
您可以通过NuGet获取它,它允许您使用xPath从htmlDoc获取节点列表。。。然后,您可以循环浏览这些列表,并对每个节点执行操作。。。
您应该使用正则表达式来解决这个问题。有关详细信息,请访问此网站。它将为您提供区分大小写/不区分大小写的匹配选项。
我查看了我的一个旧项目,在那里我做了类似的事情。
看看我一直在使用的这个方法:
private static Regex _validAttributeOrTagNameRegEx =
new Regex(@"^'w+$", RegexOptions.Compiled |RegexOptions.IgnoreCase);
private const string STR_RemoveHtmlAttributeRegex =
@"(?<=<)([^/>]+)('s{0}=['""][^'""]+?['""])([^/>]*)(?=/?>|'s)";
public static string RemoveHtmlAttribute(this string input, string attributeName) {
if (_validAttributeOrTagNameRegEx.IsMatch(attributeName)) {
Regex reg = new Regex(string.Format(STR_RemoveHtmlAttributeRegex, attributeName),
RegexOptions.IgnoreCase);
return reg.Replace(input, item => item.Groups[1].Value + item.Groups[3].Value);
} else {
throw new ArgumentException("Not a valid HTML attribute name", "attributeName");
}
}
我不确定这是否符合你的要求,但这可能是一个如何解决它的想法。在你从html标签中删除属性后,你可以使用你的旧方法convertedHtml = html.replace("</br>","<LineBreak/>");
您可以尝试一些简单的字符串操作,不需要额外的namaspaces和工具:
看看这个例子,也许它解决了你的问题:
string html = string.Concat("<p class='"foo'">",
"<p class='"bar'">",
"<p>",
"</br>",
"<P>",
"</BR>"); // tags can be upper case as well
string strAux = html;
int tagOpenedAt=-1, tagClosedAt=-1;
bool isError = false;
do
{
tagOpenedAt = strAux.IndexOf('<');
tagClosedAt = strAux.IndexOf('>');
if(tagOpenedAt<tagClosedAt)
{
string fullTag = strAux.Substring(tagOpenedAt, tagClosedAt - tagOpenedAt + 1);
//<p> --> <Paragraph>
if (fullTag.ToLower().Equals("<p>") || fullTag.ToLower().StartsWith("<p "))
html = html.Replace(fullTag, "<Paragraph>");
//</br> --> <LineBreak/>
if (fullTag.ToLower().Equals("</br>"))
html = html.Replace(fullTag, "<LineBreak/>");
//more if conditions as you need them
strAux = strAux.Substring(tagClosedAt + 1);
}
else
{
isError = true;
}
}
while (tagOpenedAt>-1 && tagClosedAt>-1 && !isError);
很抱歉代码不好,也许您可以通过简单地执行.ToLower()一次来改进,而不是在每个if语句中执行。此外,我没有检查坏标签,代码只是假设html是有效的。
刚刚编辑了一点
string html = string.Concat("<p class='"foo'">","'n",
"<p class='"bar'">", "'n",
"<p>", "'n",
"</br>", "'n",
"<P>", "'n",
"</BR>");
Console.WriteLine("HTML is :'n{0}'n", html);
string strAux = html;
int tagOpenedAt=-1, tagClosedAt=-1;
bool isError = false;
do
{
tagOpenedAt = strAux.IndexOf('<');
tagClosedAt = strAux.IndexOf('>');
if(tagOpenedAt < tagClosedAt)
{
string _fullTag = strAux.Substring(tagOpenedAt, tagClosedAt - tagOpenedAt + 1);
string _lower = _fullTag.ToLower();
string _replace = null;
//<p> --> <Paragraph>
if (_lower.Equals("<p>") || _lower.StartsWith("<p "))
_replace = "<Paragraph>";
//</br> --> <LineBreak/>
if (_lower.Equals("</br>"))
_replace = "<LineBreak/>";
//more if conditions as you need them
if(_replace != null)
{
html = html.Replace(_fullTag, _replace);
Console.WriteLine("Replaced {0} with {1}", _fullTag, _replace);
}
strAux = strAux.Substring(tagClosedAt + 1);
}
else
{
isError = true;
}
}
while (tagOpenedAt>-1 && tagClosedAt>-1 && !isError);
Console.WriteLine("'nNew html is :'n{0}",html);