Регулярное выражение для соответствия блока текста в квадратных скобках, которые могут быть вложены - PullRequest
0 голосов
/ 19 февраля 2019

Я пишу парсер в scala, который читает строку, составленную из повторений '+', '-', '<', '>' и '.'персонажи.Строка также может содержать символы '[' и ']', и внутри них есть повторение первой группы символов.Мне нужно регулярное выражение, которое соответствует всему, заключенному в квадратные скобки, проблема в том, что скобки могут быть вложенными.

Я уже пробовал использовать это регулярное выражение: \ [. * \] И многие другие, которые я нашелна SO, но ни один из них не работает.

Регулярное выражение, которое я ищу, должно работать так:

"[+++.]" соответствует "+++."

"[++ [-]]" должно соответствовать "++ [-]"

edit (добавлен вариант использования):

"[+++.] [++ [-]] "НЕ должно соответствовать" +++.] [++ [-] ", но 2 совпадения с" +++. "и "++ [-]"

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

После некоторых исследований я думаю, что, возможно, нашел решение, однако оно не применимо в Scala.Требуется рекурсивное регулярное выражение, которое соответствует сбалансированным конструкциям, в моем случае:

\[(?:[+-\[\]]|(?R))*\]

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

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

class brainfuck(var pointer: Int, var array: Array[Int]) extends JavaTokenParsers {
    def Program = rep(Statement) ^^ { _ => () }     
    def Statement: Parser[Unit] = 
        "+" ^^ { _ => array(pointer) = array(pointer) + 1 } | 
        "-" ^^ { _ => array(pointer) = array(pointer) - 1 } | 
        "." ^^ { _ => println("elem: " + array(pointer).toChar) } | 
        "," ^^ { _ => array(pointer) = readChar().toInt } |         
        ">" ^^ { _ => pointer = pointer + 1 } |
        "<" ^^ { _ => pointer = pointer - 1 } |
        "[" ~> rep(block|squares) <~ "]" ^^ { items => while(array(pointer)!=0) { parseAll(Program,items.mkString) } }

    def block = 
        """[-+.,<>]""".r ^^ { b => b.toString() }           

    def squares: Parser[String] = "[" ~> rep(block|squares) <~ "]" ^^ { b => var res = "[" + b.mkString + "]"; res }

}
0 голосов
/ 19 февраля 2019

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

def parse(s :String) :Array[String] = 
  "\\[(.*)\\]".r.unanchored
              .findAllMatchIn(s)
              .toArray
              .flatMap(_.group(1).split(raw"][^\[\]]+\["))

использование:

parse("+++.]")           //res0: Array[String] = Array()
parse("[+++.]")          //res1: Array[String] = Array("+++.")
parse("[++[-]]")         //res2: Array[String] = Array("++[-]")
parse("[+++.] [++[-]]")  //res3: Array[String] = Array("+++.", "++[-]")
parse("[++[-]--] [+]")   //res4: Array[String] = Array(++[-]--, +)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...