Scala中的递归正则表达式

时间:2016-10-06 14:24:51

标签: regex scala recursion

我有一个Scala方法,它当前接受输入并将其与正则表达式匹配:

def valiateMap(mapDef : String) : String = {
    val mapRegex = "map<([int,string,date]),([int,string,date])>".r
    mapDef match {
        case mapRegex(keyGroup, valueGroup)   =>    "Yes, we have a match!"
        case _                                =>    "'Fraid not."
    }
}

正如您所看到的,传递各种值将产生以下结果:

  • validateMap("map<int,date>") - &gt; “是的,我们有一场比赛!”
  • validateMap("fizzbuzz") - &gt; “'不要Fra。'”
  • validateMap("map<int,fizz>") - &gt; “'不要吝啬。” (fizz对正则表达式无效)

现在我需要使这个正则表达式递归,以便“valueGroup”(第二组)值本身可以是一个地图,遵循与上面相同的正则表达式。而且该地图也可以有一个地图,其价值,需要遵守相同的正则表达式。等等。

所以我需要修改正则表达式(和/或代码)来处理输入,如:

  • validateMap("map<int,map<date,string>>") - &gt; “是的,我们有一场比赛!”
  • validateMap("map<int,map<int,map<int,string>>>") - &gt; “是的,我们有一场比赛!”
  • validateMap("map<int,map<fizz,date>>") - &gt; “'不要Fra。'”

踢球者需要(可能)无限递归,并处理任意数量的内嵌式地图。

关于如何实现这一目标的任何想法?

2 个答案:

答案 0 :(得分:1)

正则表达式是一种形式化语言,用于匹配输入字符串中的某些类型的模式。正则表达式不支持的一种模式 - 作为基本定义 - 是递归嵌套模式。

@Reactormonk在其评论中提供的链接指的是尝试使用正则表达式正确解析HTML的类似问题,由于相同的递归嵌套模式匹配而失败。

由于常规录音是错误的工具,您可以考虑使用解析器组合器。指定这些将更复杂,但更普遍的情况是免提。 Scala有内置的API,或者你可以使用第三方库行fastparse。

答案 1 :(得分:0)

试试这个:

def validateMap(mapDef : String) : String = {
  val terminal = "map<(int|string|date),(int|string|date)>".r
  val arbitrary = "map<(int|string|date),(.*)>".r
  mapDef match {
    case terminal(keyGroup, valueGroup)   =>    "Yes, we have a match!"
    case arbitrary(keyGroup, valueGroup)  =>    validateMap(valueGroup)
    case _                                =>    "'Fraid not."
  }
}