在所有比赛中通过RegEx替换单个组

时间:2015-01-27 10:05:36

标签: c# .net regex

我有一个包含HTML-Elements的文本,其中超链接不包含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?

3 个答案:

答案 0 :(得分:2)

在替换中使用回调。

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
});

答案 1 :(得分:2)

不要使用正则表达式解析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标记。

现在应该按照自己的意愿行事,但为了整洁,您可以仅使用(?<RefId>\d+)替换\d+(因为您不再需要该群组),只需match.Groups["RefId"].Value替换match.Value {1}}。

答案 2 :(得分:0)

除非你从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);
}

Fiddle