我正在尝试对字符串进行模糊处理,但需要保留一些模式。基本上,所有字母数字字符都需要替换为单个字符(比如'X'),但需要保留以下(示例)模式(请注意,每个模式在开头都有一个空格)
我已经看了一些关于负向前瞻/后方的样本,但仍然没有任何运气(仅测试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
答案 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;
}