使用正则表达式转换字符串
本文关键字:字符串 转换 正则表达式 | 更新日期: 2023-09-27 18:36:22
我有一些HTML内容需要使用C#进行修改。这在概念上很简单,但我不确定如何有效地做到这一点。内容包含多次出现的分隔数字,后跟空定位标记。我需要获取分隔的数字并将其插入锚标记中的 JavaScript 函数调用中。例如
源字符串将包含如下内容:
%%1%%<a href="#"></a>
<p>A bunch of HTML markup</p>
%%2%%<a href="#"></a>
<p>Some more HTML markup</p>
我需要将其转换为:
<a href="#" onclick="DoSomething('1')></a>
<p>A bunch of HTML markup</p>
<a href="#" onclick="DoSomething('2')></a>
<p>Some more HTML markup</p>
%%''d+%% 的出现次数没有限制。我尝试编写正则表达式,希望可以使用 Replace 方法,但我不确定这是否甚至可以用于每个组的多个实例。这是我所拥有的:
%%(?<LinkID>'d+)%%(?<LinkStart><a['s'S]*?)(?:(?<LinkEnd>>['s'S]*?)(?=%%'d+|$))
// %%(?<LinkID>'d+)%% Match a number surrounded by %% and put the number in a group named LinkID
// (?<LinkStart><a['s'S]*?) Match <a followed by any characters until next match (non greedy), in a group named LinkStart
// (?: Logical grouping that does not get captured
// (?<LinkEnd>>['s'S]*?) Match > followed by any characters until next match, in a group named LinkEnd
// (?=%%'d+%%|$) Where the former LinkEnd group is followed by another instance of a delimited number or the end of the string. (I don't think this is working as I intended.)
也许可以使用几个正则表达式操作和String.Format的某种组合。我不是正则表达式的专家。
使用正则表达式来解析 HTML 已经在 SO 上进行了广泛的介绍。 共识是不应该这样做。
如果你需要解析你的HTML,我建议使用HTML敏捷包之类的东西。 这允许您使用类似于 xPath 的东西来标识要处理的 HTML。
我会说你的正则表达式几乎是你想要的 - 我稍微改变了它。如果$
仅在字符串末尾匹配,这将起作用:
%%('d+)%%(<a[^>]*)(></a>)(.*?)(?=%%'d|$)
如果您决定使用它,那么对于每个匹配项,您都可以访问组,通过这种方式,您可以构造新字符串 - 这可能比替换现有字符串中的内容更容易。
我会使用string.split来解决这个问题。
string emptyAnchor = "<a href=""#""></a>";
string src = GetData();
string[] splits = src.split(new string[]{"%%"}, StringSplitOptions.None);
StringBuilder sb = new StringBuilder();
//first entry is blank, set to 1
int i = 1;
while(i < splits.length)
{
string id = splits[i];
//increment for data string
i++;
//prehaps use a StringReplaceFirstOccurrence function instead
sb.Append(splits[i].Replace(emptyAnchor, GetDataFromID(id)));
i++;
}
string output = sb.ToString();
事实证明,Regex.Replace 已经足够智能,可以处理多个匹配项。我只是修改了我的正则表达式以不使用未来视图。这个想法是我在 %% 分隔符中找到数字并将其添加到一个组中,在下一个锚标记中找到内容并将其添加到一个组中,然后将整个匹配替换为新版本,该版本将两个组中捕获的文本插入其中。替换方法似乎会自动正确处理后续匹配项,而无需任何其他帮助。
string originalText = "<h3>%%1%%<a href='"#'">First Spot</a></h3><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>" +
"<h3>%%2%%<a href='"#'">Second Spot</a></h3><p>Ut vulputate lobortis feugiat.</p>" +
"<p>Ut nunc diam, malesuada iaculis viverra nec, auctor eget velit.</p>";
Regex regex = new Regex(@"%%('d+)%%['s]*<a['s'S]*?>(['s'S]*?)</a>");
string result = regex.Replace(originalText, "<a href='"#'" onclick='"DoSomething($1)'">$2</a>");
Debug.WriteLine("Original Text: '"" + originalText + "'"");
Debug.WriteLine("Result Text: '"" + result + "'"");
输出:
Original Text: "<h3>%%1%%<a href="#">First Spot</a></h3><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p><h3>%%2%%<a href="#">Second Spot</a></h3><p>Ut vulputate lobortis feugiat.</p><p>Ut nunc diam, malesuada iaculis viverra nec, auctor eget velit.</p>"
Result Text: "<h3><a href="#" onclick="DoSomething(1)">First Spot</a></h3><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p><h3><a href="#" onclick="DoSomething(2)">Second Spot</a></h3><p>Ut vulputate lobortis feugiat.</p><p>Ut nunc diam, malesuada iaculis viverra nec, auctor eget velit.</p>"