Я пишу сценарий AutoHotkey, который будет форматировать SQL операторов из текста, выбранного на экране. Я хочу превратить такой оператор:
SELECT Name AS [Object Name], Switch([Type]=5,'Query',[Type]=-32768,'Form',[Type]=6,'Table') AS [Object Type], Switch([Type]=5,1,[Type]=-32768,2,[Type] In (1,4,6),6) AS [Object Type ID], Left(Name,4) as Prefix, LTrim(RTrim(Mid([Name],5,30))) as Suffix
в это:
SELECT Name AS [Object Name],
Switch([Type]=5,'Query',[Type]=-32768,'Form',[Type]=6,'Table') AS [Object Type],
Switch([Type]=5,1,[Type]=-32768,2,[Type] In (1,4,6),6) AS [Object Type ID],
Left(Name,4) as Prefix,
LTrim(RTrim(Mid([Name],5,30))) as Suffix
Я начал с замены запятых на запятая + возврат каретки + табуляция , но когда Я встречал SQL операторов, содержащих функции, в которых в скобках использовались запятые, это приводило к нежелательным результатам. Мое первое решение заключалось в том, чтобы исключить запятые в скобках с помощью этой команды AutoHotkey RegEx:
; Find commas not in parenthesis and suffix with <CR><Tab>
s := RegExReplace( s, ",(?![^()]*\))", ",`r`n" . Tab )
Проблема в том, что иногда скобки вставлены, и этот простой RegEx не работает.
После немного покопавшись, я нашел рекурсивное регулярное выражение, которое выбрало бы самую внешнюю скобку для каждой группы.
\((?:[^()]++|(?R))*\)
Теперь проблема в том,
- как мне выберите все за пределами этой группы и найдите / замените в ней, или
- как применить поиск / замену только к тексту внутри этой группы?
Regex Demo
ТАК побуждает нас ответить на наш собственный вопрос. В процессе написания я нашел решение и опубликую его ниже. Не стесняйтесь делиться собственными решениями. Я хотел бы глубже понять регулярные выражения.