2015-07-21 2 views
1

Я пишу регулярное выражение в Visual Studios 2013 Express с использованием C#. Я пытаюсь поставить одиночные кавычки вокруг каждой строки, которая включает в себя слова и @ # $%^& *() _- за исключением:Regex in C# Как заменить только группы захвата, а не группы без захвата

  • и
  • или
  • не
  • пусто ()
  • notempty()
  • CurrentDate()
  • любая строка, которая уже имеет одиночные кавычки вокруг него.

Вот мое регулярное выражение и пример того, что он делает: https://regex101.com/r/nI1qP0/1

Я хочу, чтобы поместить одиночные кавычки только вокруг группы захвата и оставить группы без захвата нетронутыми. Я знаю, что это можно сделать с помощью поисковых запросов, но я не знаю, как это сделать.

ответ

1

Вместо того, чтобы игнорировать строки со словами и! @ # $%^& *() _- в них я просто включил их в свой поиск, поместил дополнительную цитату с обоих концов, а затем удалил все примеры двух одинарных котировок:

// Find any string of words and [email protected]#$%^&*()_- in and out of quotes. 
Regex getwords = new Regex(@"(^(?!and\b)(?!or\b)(?!not\b)(?!empty\b)(?!notempty\b)(?!currentdate\b)([\[email protected]#$%^&*())_-]+)|((?!and\b)(?!or\b)(?!not\b)(?!empty\b)(?!notempty\b)(?!currentdate\b)(?<=\W)([\[email protected]#$%^&*()_-]+)|('[\w\[email protected]#$%^&*()_-]+')))", RegexOptions.IgnoreCase); 
// Find all cases of two single quotes 
Regex getQuotes = new Regex(@"('')"); 

// Get string from user 
Console.WriteLine("Type in a string"); 
string search = Console.ReadLine(); 

// Execute Expressions. 
search = getwords.Replace(search, "'$1'"); 
search = getQuotes.Replace(search, "'"); 
+1

Замечательно, что вы нашли решение, которое вам подходит. Пожалуйста, подумайте над тем, чтобы ответить на ваши ответы. –

+2

Я не смог до сих пор, потому что я новичок в переполнении стека, но теперь, когда моя репутация выше 15, я могу. – brandonstrong

1

Вы можете использовать это регулярное выражение:

(?:'[^']*'|(?:\b(?:(?:not)?empty|currentdate)\(\)|and|or|not))|([[email protected]#$%^&*_.\w-]‌​+) 

Здесь игнорировал матчи не учитывается и слова в кавычках может быть получено с помощью Match.Groups[1]. Затем вы можете добавить котировки вокруг Match.Groups[1] и получить весь ввод, который вы хотите заменить.

RegEx Demo

+0

Это близко, но оно не захватывает ни одного из символов! @ # $%^& *() -_. Даже когда я добавляю их в (\ w +) часть как ([! @ # $%^& *() _-W /] +), она не работает, если они находятся в конце слов. – brandonstrong

+0

'! @ # $%^& *()' Не считаются символами слов, и вы написали ** каждое слово **. Вы можете использовать это регулярное выражение: '(?: '[^'] * '| (?: \ B (? :(?: not)? Empty | currentdate) \ (\) | и | или | not)) | ([! @ # $%^& * _ \ ш -.] +) '. См. Эту демонстрацию: https://regex101.com/r/nI1qP0/3 – anubhava

+1

Вы правы, я допустил ошибку. Извини за это. Это прекрасно работает. – brandonstrong

1

Вы должны использовать спички оценщик или метод обратного вызова. Дело в том, что вы можете проверить совпадение и захваченные группы внутри этого метода и решить, какое действие нужно предпринять в зависимости от вашего шаблона.

Итак, добавьте этот метод обратного вызова (может быть не статичным, если вызываемый метод не является статическим):

public static string repl(Match m) 
{ 
    return !string.IsNullOrEmpty(m.Groups[1].Value) ? 
     m.Value.Replace(m.Groups[1].Value, string.Format("'{0}'", m.Groups[1].Value)) : 
     m.Value; 
} 

Затем используйте overload of Regex.Replace with the match evaluator (=callback method):

var s = "'This is not captured' but this is and not or empty() notempty() currentdate() capture"; 
var rx = new Regex(@"(?:'[^']*'|(?:\b(?:(?:not)?empty|currentdate)\(\)|and|or|not))|([[email protected]#$%^&*_.\w-]+)"); 
Console.WriteLine(rx.Replace(s, repl)); 

Примечание вы можете сократить код с лямбда-выражения:

Console.WriteLine(rx.Replace(s, m => !string.IsNullOrEmpty(m.Groups[1].Value) ? 
    m.Value.Replace(m.Groups[1].Value, string.Format("'{0}'", m.Groups[1].Value)) : 
    m.Value)); 

См IDEONE demo

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