Как написать шаблон Ruby-regex на Java (включает рекурсивную именованную группировку)?

#java #ruby #regex #netbeans #recursive-regex

#java #ruby #регулярное выражение #netbeans #рекурсивное регулярное выражение

Вопрос:

хорошо… у меня есть файл, содержащий tintin-script. Теперь мне уже удалось извлечь из него все действия и замены, чтобы показать их правильно упорядоченными на веб-сайте с использованием Ruby, что помогает мне вести обзор.

Пример TINTIN-script

 #substitution {You tell {([a-zA-Z,- ]*)}, %*$}
              {<279>[<269> $sysdate[1]<279>, <269>$systime<279> |<219> Tell  <279>] <269>to   <219>%2<279> : <219>%3} 
              {4}
#substitution {{([a-zA-Z,- ]*)} tells you, %*$}  
              {<279>[<269> $sysdate[1]<279>, <269>$systime<279> |<119> Tell  <279>] <269>from <119>%2<279> : <119>%3} 
              {2}

#action {Your muscles suddenly relax, and your nimbleness is gone.}
{
    #if {$sw_keepaon}
    {
        aon;
    };
} {5}

#action {xxxxx}
{
    #if {$sw_keepfamiliar}
    {
        familiar $familiar;
    };
} {5}
  

Чтобы захватить их в моем Ruby-приложении, я читаю свой файл сценария в переменный «ввод», а затем использую следующий шаблон для сканирования «ввода»

 pattern = /(?<braces>{([^{}]|g<braces>)*}){0}^#(?<type>action|substitution)s*(?<b1>g<braces>)s*(?<b2>g<braces>)s*(?<b3>g<braces>)/im

input = ""

File.open("/home/igambin/lmud/lmud.tt") { |file| input = file.read }

input.scan(pattern) { |prio, type, pattern, code|
  ## here i usually create objects, but for simplicity only output now
  puts "Type    : #{type}"
  puts "Pattern : #{pattern}"
  puts "Priority: #{prio}"
  puts "Code    :n#{code}"
  puts
}
  

Теперь моя идея заключалась в том, чтобы использовать платформу netbeans для написания модуля, который не только сохранял бы обзор, но и помогал редактировать файл сценария tintin. Итак, открыв файл в окне редактора, мне все равно нужно проанализировать tintin-файл и получить все «действия» и «замены» из файла, захваченные и отображаемые в eTable, в котором я мог бы щелкнуть dbl по одному элементу, чтобы открыть окно модификации.

Я настроил модуль и пока все готово, я просто не могу понять, как перевести шаблон ruby-regex, который я написал, в рабочий шаблон java-regex. Кажется, что захват именованных групп и особенно рекурсивное применение этих групп не поддерживается в Java. Без этого я, похоже, не могу найти рабочее решение…

Вот снова шаблон ruby…

 pattern = /(?<braces>{([^{}]|g<braces>)*}){0}^#(?<type>action|substitution)s*(?<b1>g<braces>)s*(?<b2>g<braces>)s*(?<b3>g<braces>)/im
  

Кто-нибудь может помочь мне создать шаблон Java, который соответствует тому же?

Заранее большое спасибо за советы / подсказки / идеи и особенно за решения или (комментарии, близкие к решению)!

Комментарии:

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

Ответ №1:

Ваш текстовый формат кажется довольно простым; возможно, вам действительно не нужно рекурсивное сопоставление. Насколько я могу судить, это Java-совместимое регулярное выражение правильно соответствует вашим образцам данных:

 (?s)#(substitution|action)s*{(.*?)}s*{(.*?)}s*{(d )}
  

Это сработает для вас? Если вы запустите Java 7, вы даже можете назвать группы. 😉

Комментарии:

1. С помощью Regex Tester и RegExr шаблон сопоставляет только блоки #substitution и игнорирует блоки #action .

2. Извините, я забыл добавить (?s) модификатор для режима DOTALL (то, что Ruby называет «многострочным» режимом).

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

Ответ №2:

Кто-нибудь может помочь мне создать шаблон Java, который соответствует тому же?

Нет, никто не может: механизм регулярных выражений Java не поддерживает рекурсивные шаблоны (как это делает Ruby 1.9).

Комментарии:

1. я уже это выяснил, но нет ли способа воспроизвести шаблон без рекурсии?

2. Разве этого нельзя достичь, используя Pattern класс для компиляции регулярного выражения, а затем создавая Matcher для строки, перебирая, чтобы захватить группы, которые ему соответствуют? Возможно, я полностью недопонимаю.

3. @Ingo, ошибка, шаблон вызывает сам себя, заставляя его (теоретически) соответствовать бесконечному количеству вложенных совпадений. Так что нет, это не может быть выражено с помощью механизма регулярных выражений, который не поддерживает рекурсию.

4. итак, мне придется в конечном итоге использовать нерекурсивный шаблон, а затем написать дополнительный код для проверки правильности вложенности для каждой «группы», которая может содержать вложенные совпадения?

5. @Ingo, да, если это возможно сделать с помощью движка, который не поддерживает рекурсивные шаблоны (я слишком мало знаю о языке, который вы пытаетесь обработать).