在所有比赛中通过 RegEx 替换单个组
Replace single group via RegEx in all matches
我有一个包含 HTML 元素的文本,其中超链接不包含 URL,而是包含超链接应打开的项目的 ID。现在我正在尝试获取所有这些 ID 并用新 ID 替换它们。场景是,所有 ID 都已更改,我有一个包含 "oldId -> newID" 的字典,需要在文本中替换它。
这个输入
Some text some text <a href = "##1234"> stuff stuff stuff <a href="##9999"> xxxx
有了这个字典映射
1234 -> 100025
9999 -> 100026
应该生成此输出
Some text some text <a href = "##100025"> stuff stuff stuff <a href="##100026"> xxxx
到目前为止我有这个:
var textContent = "...";
var regex = new Regex(@"<\s*a\s+href\s*=\s*""##(?<RefId>\d+)""\s*\?\s*>");
var matches = regex.Matches(textContent);
foreach (var match in matches.Cast<Match>())
{
var id = -1;
if (Int32.TryParse(match.Groups["RefId"].Value, out id))
{
int newId;
// idDictionary contains the mapping from old id to new id
if (idDictionary.TryGetValue(id, out newId))
{
// Now replace the id of the current match with the new id
}
}
}`
我现在如何更换 ID?
除非您也从 HTML 中提取新 ID,否则我不明白为什么您不能在此处直接使用 String.Replace
var html = "Some text some text <a href = '##1234'> stuff stuff stuff <a href='##9999'> xxxx";
var mappings = new Dictionary<string, string>()
{
{ "1234", "100025" },
{ "9999", "100026" },
...
};
foreach (var map in mappings)
{
html = html.Replace("##" + map.Key, "##" + map.Value);
}
只需在替换中使用回调即可。
regex.Replace(textContent, delegate(Match m) {
int id = -1, newId;
if (Int32.TryParse(m.Groups["RefId"].Value, out id)) {
if (idDictionary.TryGetValue(id, out newId))
return newId.ToString();
}
return m.Value; // if TryGetValue fails, return the match
});
不要用正则表达式解析 HTML。
但是,如果您必须尝试执行替换,请使用 Replace 方法。
var updatedContent = regex.Replace(textContent, match =>
{
var id = -1;
if (Int32.TryParse(match.Groups["RefId"].Value, out id))
{
int newId;
// idDictionary contains the mapping from old id to new id
if (idDictionary.TryGetValue(id, out newId))
{
// Now replace the id of the current match with the new id
return newId.ToString();
}
}
// No change
return match.Value;
});
编辑:正如您所指出的,这取代了整个匹配。哎呀
首先,更改您的正则表达式,以便您要替换的内容 是 整个匹配项:
@"(?<=<\s*a\s+href\s*=\s*""##)(?<RefId>\d+)(?=""\s*\?\s*>)"
这只匹配一串数字,但确保它前后都有 HTML 标记。
它现在应该做你想做的事,但为了整洁你可以用 \d+
替换 (?<RefId>\d+)
(因为你不再需要组了)和 match.Groups["RefId"].Value
与只是 match.Value
.
我有一个包含 HTML 元素的文本,其中超链接不包含 URL,而是包含超链接应打开的项目的 ID。现在我正在尝试获取所有这些 ID 并用新 ID 替换它们。场景是,所有 ID 都已更改,我有一个包含 "oldId -> newID" 的字典,需要在文本中替换它。
这个输入
Some text some text <a href = "##1234"> stuff stuff stuff <a href="##9999"> xxxx
有了这个字典映射
1234 -> 100025
9999 -> 100026
应该生成此输出
Some text some text <a href = "##100025"> stuff stuff stuff <a href="##100026"> xxxx
到目前为止我有这个:
var textContent = "...";
var regex = new Regex(@"<\s*a\s+href\s*=\s*""##(?<RefId>\d+)""\s*\?\s*>");
var matches = regex.Matches(textContent);
foreach (var match in matches.Cast<Match>())
{
var id = -1;
if (Int32.TryParse(match.Groups["RefId"].Value, out id))
{
int newId;
// idDictionary contains the mapping from old id to new id
if (idDictionary.TryGetValue(id, out newId))
{
// Now replace the id of the current match with the new id
}
}
}`
我现在如何更换 ID?
除非您也从 HTML 中提取新 ID,否则我不明白为什么您不能在此处直接使用 String.Replace
var html = "Some text some text <a href = '##1234'> stuff stuff stuff <a href='##9999'> xxxx";
var mappings = new Dictionary<string, string>()
{
{ "1234", "100025" },
{ "9999", "100026" },
...
};
foreach (var map in mappings)
{
html = html.Replace("##" + map.Key, "##" + map.Value);
}
只需在替换中使用回调即可。
regex.Replace(textContent, delegate(Match m) {
int id = -1, newId;
if (Int32.TryParse(m.Groups["RefId"].Value, out id)) {
if (idDictionary.TryGetValue(id, out newId))
return newId.ToString();
}
return m.Value; // if TryGetValue fails, return the match
});
不要用正则表达式解析 HTML。
但是,如果您必须尝试执行替换,请使用 Replace 方法。
var updatedContent = regex.Replace(textContent, match =>
{
var id = -1;
if (Int32.TryParse(match.Groups["RefId"].Value, out id))
{
int newId;
// idDictionary contains the mapping from old id to new id
if (idDictionary.TryGetValue(id, out newId))
{
// Now replace the id of the current match with the new id
return newId.ToString();
}
}
// No change
return match.Value;
});
编辑:正如您所指出的,这取代了整个匹配。哎呀
首先,更改您的正则表达式,以便您要替换的内容 是 整个匹配项:
@"(?<=<\s*a\s+href\s*=\s*""##)(?<RefId>\d+)(?=""\s*\?\s*>)"
这只匹配一串数字,但确保它前后都有 HTML 标记。
它现在应该做你想做的事,但为了整洁你可以用 \d+
替换 (?<RefId>\d+)
(因为你不再需要组了)和 match.Groups["RefId"].Value
与只是 match.Value
.