Соответствие (и замена) групп текста в строке - PullRequest
0 голосов
/ 26 мая 2010

У меня есть строка в следующем формате:

бла IIF ((doc.PostTypeId == 1), (Parse (doc.Id)> 1000), (doc.ParentId> 1000)) бла

и я хочу преобразовать его в:

бла (doc.PostTypeId == 1? Parse (doc.Id)> 1000: doc.ParentId> 1000) бла

Пока что я использую следующую строку регулярного выражения для совпадения

IIF\((?<one>[^,]*?),\ (?<two>[^,]*?),\ (?<three>[^,]*)\)

Но у меня проблемы с балансировкой всех скобок, есть ли лучший способ или regex не тот инструмент для этого?

1 Ответ

1 голос
/ 27 мая 2010

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

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

Легко найти последовательность без скобок:

EXPR0:  [^()]*

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

PAREN1:   \(EXPR0\)

Что такое выражение, содержащее до одного уровня скобок? Ну, это просто смесь PAREN1 с символами без скобок:

EXPR1:    (?:PAREN1|EXPR0)*

учитывая, что мы можем, конечно, сопоставить сбалансированное выражение в скобках с одним уровнем вложенности:

PAREN2:    \(EXPR1\)

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

EXPR2: (?:PAREN2|EXPR0)*

и т. Д .:

PAREN3:    \(EXPR2\)
EXPR3:     (?:PAREN3|EXPR0)
PAREN4:    \(EXPR3\)
...

Затем вы можете использовать это для построения соответствия для замены, которую вы хотите сделать - что-то вроде:

IIF\(?<one>EXPR5),(?<two>EXPR5),(?<three>EXPR5)\)

(на самом деле вам нужно настроить параметры так, чтобы выражения EXPR5 не совпадали с запятыми без скобок, но должно быть достаточно ясно, как это сделать, я надеюсь:)

Конечно, стоит написать короткую одноразовую программу для генерации требуемого т. Е. вместо того, чтобы создавать его вручную!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...