Regex, чтобы получить все возможные совпадения для шаблона в C # - PullRequest
1 голос
/ 12 марта 2009

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

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

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

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

Group1:

  1. "cond1"
  2. "stmt1;"

и группа 2:

  1. "cond2"
  2. "stmt2;"

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

Ответы [ 3 ]

6 голосов
/ 12 марта 2009

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

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

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

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

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

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

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

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;

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

1 голос
/ 12 марта 2009

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

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

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

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

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

0 голосов
/ 12 марта 2009

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

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% в паттерне ... но я бы возился с этим.

...