1

Scala 正则表达式在以下两种情况下都可以很好地工作:
无条件执行的代码:例如

val lineregx = """([\w]+)\t([/\w.+-]+)\t([/\w+=\-!%# ]+)""".r
val anotherregx = """([\w]+)\t([/\w+=\-!%# ]+)""".r
val lineregx(category, aaUrl, title) 

或者如果在 case 语句中我们使用表达式(并且不再需要它们..)

val lineregx = """([\w]+)\t([/\w.+-]+)\t([/\w+=\-!%# ]+)""".r
line match {

case lineregx(category, aaUrl, title) => // do something with category, aaUrl and title in here!
case anotherRegx(category, aaUrl) => // do something different with category, aaUrl and title in here!
case _ => { println("did not match line %s".format(line)); return 0 }

}

但是,如果我需要将匹配项“显示”到 case 语句之外的变量呢?特别是下面显示的var,

val lineregx = """([\w]+)\t([/\w.+-]+)\t([/\w+=\-!%# ]+)""".r
var category = "" ; var aaUrl = "";var title = ""
line match {
case lineregx(category, aaUrl, title) => val lineregx(category, aaUrl, title) = line
case anotherRegx(category, aaUrl) => val lineregx(category, aaUrl) = line
case _ => { println("did not match line %s".format(line)); return 0 }
}
// Do something with category, aaUrl, title HERE after the case statement.

问题是,应用 lineregx/anotherregex 的语法使这些变量仅对 case 语句是局部的。

4

2 回答 2

3

大致,

val lineregx = """([\w]+)\t([/\w.+-]+)\t([/\w+=\-!%# ]+)""".r
val (category, aaUrl, title) = line match {
  case lineregx(category, aaUrl, title) => (category, aaUrl, title)
  case anotherRegx(category, aaUrl) => (category, aaUrl, ???)
  case _ => { println("did not match line %s".format(line)); return 0 }
}
// Do something with category, aaUrl, title HERE after the case statement.

但是该代码非常杂乱无章。一方面,存在title第二种情况的价值问题。另一方面,还有早期的回报。相反,代码可能最好像这样组织:

// method declaration
// ...
  val lineregx = """([\w]+)\t([/\w.+-]+)\t([/\w+=\-!%# ]+)""".r
  line match {
    case lineregx(category, aaUrl, title) => f(category, aaUrl, title)
    case anotherRegx(category, aaUrl)     => f(category, aaUrl, ???)
    case _ => 
      println("did not match line %s".format(line))
      0
  }
}  // end of method

def f(category: String, aaUrl: String, title: String): Int = {
  // Do something with category, aaUrl, title HERE
}
于 2013-01-22T04:15:06.123 回答
2

你可以使用Option

val lineregx = """([\w]+)\t([/\w.+-]+)\t([/\w+=\-!%# ]+)""".r

val (maybeCat, maybeUrl, maybeTitle) = 
line match {
  case lineregx(category, aaUrl, title) => (Some(category), Some(aaUrl), Some(title))
  case anotherRegx(category, aaUrl)     => (Some(category), Some(aaUrl), None)
  case _ => 
    println("did not match line %s".format(line))
    (None, None, None)
}

var category = maybeCat getOrElse ""
var aaUrl =    maybeURL getOrElse ""
var title =    maybeTitle getOrElse  ""

稍微冗长一些,但是这样你可以在相同的范围内获取变量。

于 2013-01-22T05:17:45.727 回答