2013-12-18 6 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: no вы не можете, потому что один «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 –

Смежные вопросы