2017-01-14 2 views
1

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

func anyword() { 

Узор будет делать это, но я хочу остановиться на следующем }. Но если один или несколько из этого появляется:

SomeFunction(); 

он должен пропустить следующий }.

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

override func something() { // here is a start pattern 
           // still looking for an } 
halloworld() { };    // bracket } found but is ignored because line also contains "()" 
           // still looking for an } 
           // still looking for an } 
}        // found closing bracket } end of match 

Это шаблон, который я в настоящее время с помощью:

\w+\s+func\s\w+\(\)\{\s+(.*?)\s+\} 
+1

regex не поставляется из коробки для сопоставления произвольного числа вложенных конструкций. но .net regex добавляет регулярное выражение только для этого: https://msdn.microsoft.com/en-us/library/bs2twtah(v=vs.110).aspx#balancing_group_definition – sweaver2112

ответ

2

может быть что-то, что использует .NET Balancing Groups (чтобы справиться с остроумием ч надоедливые вложенными, неизвестные уровни {}:

\bfunc\s*\w+\([^)]*\)\s*{(?:[^{}]|(?<Open>{)|(?<-Open>}))*(?(Open)(?!)\} 

прохладная часть (?:[^{}]|(?<Open>{)|(?<-Open>}))*(?(Open)(?!) это переводится: есть либо одну не {}, или съесть {, а затем, в конце концов, по }, третий вариант в 3-полосная чередование (обратите внимание на знак минуса, имя не имеет значения), это всплывает стек и «закрывает» группу. Этот подзадач можно соединить как можно чаще из-за *, но любой { должен быть сопоставлен тем же числом }, или шаблон завершится неудачей через последнее условие, которое проверяет группу «Открыть» , и если он держит любые совпадения по-прежнему, выполняет пустой просмотр, гарантирующий потерю всего этого.

+0

Вы указываете «^» для 'func' в начале строки, но в данных данного образца это * not * в начале строки. – Abion47

+0

«строка начинается с» => 'RegexOptions.Multiline' – sweaver2112

+0

Затем требуется уточнение, поскольку данные примера явно не соответствуют этому настрою. – Abion47

0

Возможное решение это, вы должны использовать одну строку совпадение для точки, соответствующей символам новой строки:

func\s*.*\s*{\n.*?((?!\{.*\}).)*} 

Здесь вы соответствуете ключевому слову func и первому открывающему кронштейну. Затем вы используете отрицательный lookahead, который не позволяет использовать другую открывающую скобку на этой строке, за которой следует искомая закрывающая скобка.

Вы можете даже вложить больше открывающих и закрывающих скобок, и он будет соответствовать последнему закрывающему кронштейну.

Вы можете проверить его here

Для получения дополнительной информации см this question

+1

Когда я помещаю это в [Regex101] (https://regex101.com/r/So2MRV/1), он ничего не соответствует. – Abion47

+0

@ Abion47 https://regex101.com/r/hXdRNe/2 – freinn

+0

https: // regex101.com/r/NvZJ7n/1 – Abion47

0

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

\w[\w\s]+func[\w\s()]+({(?:[^{}]*|[\w\s();]*?{[\w\s();]*?}[\w\s();]*?)*}) 

See it implemented on Regex101.

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