替换除pattern之外的字符串中的所有字母数字字符

时间:2013-12-18 19:57:15

标签: c# regex

我正在尝试对字符串进行模糊处理,但需要保留一些模式。基本上,所有字母数字字符都需要替换为单个字符(比如'X'),但需要保留以下(示例)模式(请注意,每个模式在开头都有一个空格)

  • QQQ“
  • RRR“

我已经看了一些关于负向前瞻/后方的样本,但仍然没有任何运气(仅测试QQQ)。

var test = @"""SOME TEXT       AB123 12XYZ QQQ""""empty""""empty""1A2BCDEF";
var regex = new Regex(@"((?!QQQ)(?<!\sQ{1,3}))[0-9a-zA-Z]");            
var result = regex.Replace(test, "X");  

正确的结果应该是:

"XXXX XXXX       XXXXX XXXXX QQQ""XXXXX""XXXXX"XXXXXXXX

这适用于完全匹配,但会因“返回

”等“QQR”而失败
"XXXX XXXX       XXXXX XXXXX XQR""XXXXX""XXXXX"XXXXXXXX

2 个答案:

答案 0 :(得分:4)

您可以使用:

var regex = new Regex(@"((?> QQQ|[^A-Za-z0-9]+)*)[A-Za-z0-9]");            
var result = regex.Replace(test, "$1X");

我们的想法是匹配所有必须首先保留的内容并将其放入捕获组中。

由于目标字符总是先于零或多个必须保留的内容,因此您只需在[A-Za-z0-9]之前编写此捕获组

答案 1 :(得分:2)

这是一个非正则表达式解决方案。工作相当不错,但是当输入序列中有一个模式超过一次时,它会失败。它需要一个更好的算法来获取出现。您可以将它与大型字符串的正则表达式解决方案进行比较。

public static string ReplaceWithPatterns(this string input, IEnumerable<string> patterns, char replacement)
{
    var patternsPositions = patterns.Select(p => 
           new { Pattern = p, Index = input.IndexOf(p) })
           .Where(i => i.Index > 0);

    var result = new string(replacement, input.Length);
    if (!patternsPositions.Any()) // no pattern in the input
        return result;

    foreach(var p in patternsPositions)
        result = result.Insert(p.Index, p.Pattern); // return patterns back

    return result;
}