2013-12-18 63 views
5

我试图混淆字符串,但需要保留几个模式。基本上,所有字母数字字符需要与单个字符代替(说“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 

回答

4

您可以使用这个:

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

这个想法是要匹配所有必须首先保存的内容并将其放入捕获组。

由于目标人物总是由零个或更多的东西必须保留之前,你只需要前[A-Za-z0-9]

+0

@hwnd:不可以,因为一个'Q'不匹配。 –

+0

我必须误解他想做的事情。我以为他想保留QQQ和RRR – hwnd

+0

+1也许你应该修改一下正则表达式变成'((?>(?:Q | R){3}“”| [^ A-Z0-9] +) *)[A-Z0-9]'只是因为它接受双引号和'RRR''(并使用ignorecase)。 – Jerry

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; 
} 
+0

我辩论过这样做的非正则表达式版本,因为字符串永远不会很大,但内心深处,我觉得必须有一种方法来使用正则表达式......我只需要确保我对它进行评论或我会忘记下周会做些什么。 – Matt

+0

@tencntraze是的,这正是我的问题与正则表达式:D –

相关问题