0

在解析一些复杂的文本时,出于重用和可读性的原因,我需要拆分正则表达式定义,我似乎经常以这种通用结构的 Scala 代码结束(pn- 一个正则表达式模式,vn一个变量):

val cp1 = p1 ~ p2 ~ p3 ~ p4 ~ p5 ~ p6 ^^
          case { dummy1 ~ v2 ~ dummy3 ~ v4 ~ dummy5 ~ v6 => ACaseClass(v2, v4, v6) }

显而易见的问题是代码的可读性和可维护性,因为需要插入新模式,因为有用的匹配项 ( vn) 与占位符匹配项 () 是分开的dummyn

那么,有没有更简洁的方式来表达意图呢?我可以用_每个代替dummyn吗?

在 SNOBOL 语言中,可以写(pat . var)or (pat $ var)which 将匹配的结果分配给变量;同样,在最新的正则表达式语法中,我们将捕获组命名为(?P<name>pat)。目的显然是使匹配捕获变量接近模式。

所以,我想写的是大致的内容:

val cp1 = p1 ~ ( p2 $$ v2 )  ~ p3 ~ ( p4 $$ v4 ) ~ p5 ~ ( p6 $$ v6 ) $=>
          ACaseClass(v2, v4, v6)

显然,我假设了某种新的运算符$$,并$=>启用了这种更简单的语法。

可以想象宏可以提供帮助,但它们目前超出了我的能力范围。欢迎任何输入!

4

1 回答 1

2

你为什么不尝试使用_?事实证明它有效。您也可以使用~><~丢弃部分模式,但如果要丢弃内部部分,则需要使用括号。

object SimpleScala extends JavaTokenParsers {

  def test = "(" ~> wholeNumber ~ ("," ~> wholeNumber <~ ",") ~ wholeNumber <~ ")" ^^ 
    { case i1 ~ i2 ~ i3 => (i1,i2,i3) }

  def test2 = "(" ~ wholeNumber ~ "," ~ wholeNumber ~ ")" ^^ 
    { case _ ~ i1 ~ _ ~i2 ~ _ => (i1,i2) }

  def main(args: Array[String]){
    println(parseAll(test,"(42,34,5)"))
    println(parseAll(test2,"(42,345)"))
  }
}
于 2013-05-31T21:53:06.183 回答