您将如何实现通过正则表达式解析某些输入并将创建的字符串转换为其他类型的类?我的方法是:
class ARegex[T](regex:Regex, reform:Option[String => T]){
def findFirst(input:String):Option[T] = {
(regex.findFirstIn(input), reform) match{
case (None, _) => None
case (Some(s), None) => Some(s) // this won't compile because of type mismatch
case (Some(s), Some(fun)) => Some(fun(s))
}
}
}
class BRegex[T](regex:Regex, reform:Option[String => T]) {
def findFirst(input:String) = { //returns Option[Any] - erasure
(regex.findFirstIn(input), reform) match{
case (None, _) => None
case (Some(s), None) => Some(s)
case (Some(s), Some(fun)) => Some(fun(s))
}
}
}发布于 2010-07-14 01:39:24
我们可以通过删除reform类型中的Option部分来解决这个问题,并使用不同的机制来表明我们不想以任何方式更改匹配。这个机制是使用identity作为默认参数,或者在您不想更改类型时传递标识。
class ARegex[T](regex:Regex, reform:String => T = identity[String](_)){
def findFirst(input:String):Option[T] = {
regex.findFirstIn(input) match{
case None => None
case Some(s) => Some(reform(s))
}
}
}
new ARegex("something".r).findFirst("something else") //returns Option[String]
new ARegex("3".r, {x=>x.toInt}).findFirst("number 3") //returns Option[Int]发布于 2010-07-13 23:40:51
嗯,问题在于类型不匹配,因为您返回的是String或T,当然,这两个值在Any中是统一的。您不能先说要返回Option[T],然后再返回Option[String]。
除此之外,该代码的简化版本如下:
class ARegex[T](regex: Regex, reform: Option[String => T]) {
def findFirst(input: String): Option[Any] =
regex findFirstIn input map { s => reform map (_(s)) getOrElse s }
}不过,您可以返回一个Option[Either[String, T]]。代码将如下所示:
class ARegex[T](regex: Regex, reform: Option[String => T]) {
def findFirst(input: String): Option[Either[String, T]] =
regex findFirstIn input map { s => reform map (_(s)) toRight s }
}发布于 2010-07-13 23:45:24
为什么是reform => T而不只是String => T?如果您没有传入用于创建所需类型的实例的机制,则运行时系统没有机制来实际创建适当的对象。如果您确实需要传入一个OptionString => T,那么您的第二个案例应该简单地返回None。
此外,flatMap是您的朋友,它会给您正确的行为(即,如果reform为None,该方法将返回None。
class RegexExtractor[T](regex: Regex, reform: Option[String => T]) {
def findFirst(input: String): Option[T] = reform.flatMap(f => regex.findFirstIn(input).map(f))
}https://stackoverflow.com/questions/3238591
复制相似问题