2015-04-16 2 views
8

У меня есть выражение, которое подчиняется некоторым правилам:Каким будет это регулярное выражение?

  • Символ 'должен быть первый и последний символ
  • Там могут быть нулевыми или-больше пространства внутри ''
  • Там может быть нулевым или- более % внутри ''
  • Там могут быть нулевыми или-больше слов (буквы и цифры) внутри ''

Ex прижимной:

(?i)^(?<q>['])[%\p{Zs}\p{L}\p{N}|()]*\k<q>$ 

Теперь мне нужно другое выражение, чтобы заменить все) и (в строке для «TEST», например, но только тогда, когда они не окружены «». Хитрость заключается в том, что, когда) или (окружены «», но эти персонажи принадлежат к другой паре «», он не должен проходить

Пример результатов:.

'(' > pass 
    ' (' > pass 
    ')' > pass 
    ') ' > pass 
    ' content here ' ')' > pass 
    ' content here') ' another content' > does not pass 

Обратите внимание, что первый

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

+0

Что касается учебников, я бы предпочел рекомендовать книги ... особенно те, кто из o'reilly действительно отрезал его –

ответ

3

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

^.*[()](?=[^']*'(?>(?:[^']*'[^']*){2})*$) 

См demo.

Код:

var rgxHardNut = new Regex(@"^.*[()](?=[^']*'(?>(?:[^']*'[^']*){2})*$)"); 
var check1 = rgxHardNut.IsMatch("'('"); // true 
var check2 = rgxHardNut.IsMatch("' ('");// true 
var check3 = rgxHardNut.IsMatch("')'"); // true 
var check4 = rgxHardNut.IsMatch("') '");// true 
var check5 = rgxHardNut.IsMatch("' content here ' ')'"); // true 
var check6 = rgxHardNut.IsMatch("' content here') ' another content'"); // false 
+0

Я думаю, что все это сейчас. Флориан, 'Символ 'должен быть первым и последним символом' - это условие для регулярного выражения OP. Теперь это другое регулярное выражение, которое не должно проверять этот критерий. –

+0

Мне понадобилось 1 час, чтобы выяснить регулярное выражение, но как 2 минуты, чтобы просто закодировать алгоритм ... –

+0

@ Th3B0Y: Пожалуйста, дайте мне знать, если вам нужна дополнительная помощь в решении этой проблемы. Если нет, подумайте о том, чтобы принять ответ, который сработал для вас. –

3

Я думаю, что это нужно сделать, это:

Regex regex = new Regex(@"^'[^']*?'(?:(?:[^()]*)'[^']*?')*$"); 

Редактировать Demo

class Program 
{ 
    static void Main(string[] args) 
    { 
     Regex regex = new Regex(@"^'[^']*?'(?:(?:[^()]*)'[^']*?')*$"); 

     string shouldPass1 = "'('"; 
     string shouldPass2 = "' ('"; 
     string shouldPass3 = "')'"; 
     string shouldPass4 = "'('"; 
     string shouldPass5 = "' content here ' ')'"; 
     string shouldFail = "' content here') ' another content'"; 

     Console.WriteLine("Pass1 : {0}",regex.IsMatch(shouldPass1)); 
     Console.WriteLine("Pass2 : {0}", regex.IsMatch(shouldPass2)); 
     Console.WriteLine("Pass3 : {0}", regex.IsMatch(shouldPass3)); 
     Console.WriteLine("Pass4 : {0}", regex.IsMatch(shouldPass4)); 
     Console.WriteLine("Pass5 : {0}", regex.IsMatch(shouldPass5)); 
     Console.WriteLine("Fail : {0}", regex.IsMatch(shouldFail)); 

     string wholeThing = string.Format(
      "{0}\n{1}\n{2}\n{3}\n{4}\n{5}", 
      shouldPass1, 
      shouldPass2, 
      shouldPass3, 
      shouldPass4, 
      shouldPass5, 
      shouldFail); 

     Console.WriteLine("Alltogether (should fail too): {0}", regex.IsMatch(wholeThing)); 
    } 
} 

Или без Regex (Tim Schmelter гордился бы мной):

private static bool IsMatch(string text) 
{ 
    bool result = text[0] == '\'' && text[text.Length - 1] == '\''; 
    bool opened = false; 

    for (int i = 0; result && i < text.Length; i++) 
    { 
     char currentchar = text[i]; 

     if (currentchar == '\'') 
     { 
      opened = !opened; 
     } 
     if (!opened && (currentchar == '(' || currentchar == ')')) 
     { 
      result = false; 
     } 
    } 

    return result; 
} 
Смежные вопросы