Scala中的括号匹配---功能方法 [英] Parentheses matching in Scala --- functional approach

查看:123
本文介绍了Scala中的括号匹配---功能方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想分析一个带有各种开放和关闭括号的字符串(我在标题中使用了括号,因为我相信它更常见 - 但问题仍然相同),以便我将所有更高级别的字符分隔开一个列表。



鉴于:

  [hello:= [notting ],[hill]] [3.4(4.56676 | 5.67787)] [hill [is [high]]不是]] 

我想:

 列表([hello:= [notting],[hill]] [3.4(4.56676 | 5.67787)],[[hill [is [high]] not]])

我这样做的方式是通过计算开始和结束括号并在我的计数器为0时添加到列表中。但是,我有一个难看的命令代码。您可能会认为原始字符串格式正确。



我的问题是:对这个问题有什么好的功能方法?



注意:我曾想过使用for ... yield构造,但考虑到使用计数器,我无法获得一个简单的条件(我必须有条件才能更新计数器),而且我也没有知道如何在这种情况下使用这个构造。

解决方案

使用Scala解析器组合器库的快速解决方案:

  import util.parsing.combinator.RegexParsers 

对象Parser extends RegexParsers {
lazy val t =[^ \\\ [\\] \\\(\\)] +。r

def paren:Parser [String] =
((〜〜 rep1(t | paren)〜)|
[〜〜rep1(t | paren)〜])^^ {
case o〜l〜c => (o :: l ::: c :: Nil)mkString
}

def all = rep(paren)

def apply(s:String )= parseAll(all,s)
}

在REPL中检查它:

  scala>解析器([hello:= [notting],[hill]] [3.4(4.56676 | 5.67787)] [hill [is [high]]])
res0:Parser.ParseResult [List [ String []] = [1.72] parsed:List([hello:= [notting],[hill]],[3.4(4.56676 | 5.67787)] [[hill [is [high]]])


Let's say I want to parse a string with various opening and closing brackets (I used parentheses in the title because I believe it is more common -- the question is the same nevertheless) so that I get all the higher levels separated in a list.

Given:

[hello:=[notting],[hill]][3.4(4.56676|5.67787)][the[hill[is[high]]not]]

I want:

List("[hello:=[notting],[hill]]", "[3.4(4.56676|5.67787)]", "[the[hill[is[high]]not]]")

The way I am doing this is by counting the opening and closing brackets and adding to the list whenever I get my counter to 0. However, I have an ugly imperative code. You may assume that the original string is well formed.

My question is: what would be a nice functional approach to this problem?

Notes: I have thought of using the for...yield construct but given the use of the counters I cannot get a simple conditional (I must have conditionals just for updating the counters as well) and I do not know how I could use this construct in this case.

解决方案

Quick solution using Scala parser combinator library:

import util.parsing.combinator.RegexParsers

object Parser extends RegexParsers {
  lazy val t = "[^\\[\\]\\(\\)]+".r

  def paren: Parser[String] =
    ("(" ~ rep1(t | paren) ~ ")" |
     "[" ~ rep1(t | paren) ~ "]") ^^ {
      case o ~ l ~ c => (o :: l ::: c :: Nil) mkString ""
    }

  def all = rep(paren)

  def apply(s: String) = parseAll(all, s)
}

Checking it in REPL:

scala> Parser("[hello:=[notting],[hill]][3.4(4.56676|5.67787)][the[hill[is[high]]not]]")
res0: Parser.ParseResult[List[String]] = [1.72] parsed: List([hello:=[notting],[hill]], [3.4(4.56676|5.67787)], [the[hill[is[high]]not]])

这篇关于Scala中的括号匹配---功能方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆