2009-03-12 2 views
1

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

Если мой вход:

case a 
when cond1 
then stmt1; 
when cond2 
then stmt2; 
end case; 

Мне нужно, чтобы получить матчи, которые имеют группы следующим образом

Group1:

  1. "cond1"
  2. "stmt1;"

и Group2:

  1. "cond2"
  2. "stmt2;"

Можно ли получить такие группы с помощью любого регулярного выражения?

+0

Я не думаю, что понимаю. Что ваш код должен делать с регулярными выражениями? – Grzenio

+0

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

+0

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

ответ

6

Для этого можно использовать регулярное выражение при условии, что вы не вставляете свои утверждения. Например, если ваш stmt1 - это еще один случай, тогда все ставки отключены (вы не можете использовать регулярное выражение для чего-то подобного, вам нужен регулярный парсер).

Edit: Если вы действительно хотите попробовать его, вы можете сделать это с чем-то вроде (не проверял, но вы получите идею):

Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?;)", RegexOptions.Singleline) 
allMatches = t.Matches(input_string) 

Но, как я сказал, что это будет работать только для не вложенных операторов.

Редактировать 2: Изменено некоторое регулярное выражение, чтобы включить точку с запятой в последней группе. Это не будет работать так, как вы хотели - вместо этого он даст вам несколько совпадений, и каждое совпадение будет представлять один , когда условие, с первой группой условие и второе группа заявление.

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

Edit 3: New регулярное выражение - должно обрабатывать несколько операторов

Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?)(?=(when|end))", RegexOptions.Singleline) 

Он содержит положительный предпросмотр так, что вторая группа совпадает с затем к следующему «когда» или «конец». В моем тесте он работал с этим:

case a 
when cond1 
then stmt1; 
    stm1; 
    stm2;stm3 
when cond2 
then stmt2; 
    aaa; 
    bbb; 
end case; 

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

+0

yes, thats right, но для этого я могу проверить на следующее возникновение случая и вынуть строку перед тем, чтобы применить шаблон к нему и получить все возможные совпадения. Итак, можете ли вы помочь в создании регулярного выражения? – Archie

+0

ну, я пробовал это регулярное выражение, но он не работает. также, в соответствии с выражением case в pl/sql после этого может быть несколько операторов. – Archie

+0

Редактировать 3 привело к двум матчам с тремя группировками (cond1 stmt1; when) в каждом матче. – Will

0

Если бы это было написано в java, я бы написал два шаблона для синтаксического анализатора, один из которых соответствовал случаям и один, чтобы соответствовать случаям when-then.Вот как последний может быть написано:

CharSequence buffer = inputString.subSequence(0, inputString.length()); 
// inputString is the string you get after matching the case statements... 

Pattern pattern = Pattern.compile(
    "when (\\S+).*" 
    + "then (\\S+).*"); 

Matcher matcher = pattern.matcher(buffer); 
while (matcher.find()) { 
    DoWhenThen(matcher.group(1), matcher.group(2)); 
} 

Примечание: Я не проверял этот код, я не уверен на 100% по образцу ... но я бы мастерить вокруг этого.

+0

Большое спасибо, но я должен реализовать его в C#. – Archie

1

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

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

(?:when(.*)\nthen(.*)\n)+? 

, что приводит к:

Матч 1:
* Группа 1: cond1
* Группа 2: stmt1;
Match 2:
* Группа 1: cond2
* Группа 2: stmt2;

+0

Большое спасибо. но это регулярное выражение работает только тогда, когда на новой строке. Так что пробовал модифицировать его как (?: When (. *) \ S + then (. *) \ S *) +? но все же он не работает. – Archie

+0

Хмм, я скопировал ваш пример текста и протестировал его. Может быть, ваши данные разные? У меня нет никаких параметров регулярных выражений (нет SingleLine, no MultiLine). Не «когда» начинается с новой строки? – Will

+0

не обязательно. Я не думаю, что он дает синтаксическую ошибку, если «когда» не начинается с новой строки. – Archie

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