Scala:列表/序列上的正则表达式
是否有一种系统的方法来搜索任意给定序列中的子序列模式?从某种意义上说,它类似于正则表达式,但在元素序列之上 更具体地说,我们希望完成此功能Scala:列表/序列上的正则表达式,scala,Scala,是否有一种系统的方法来搜索任意给定序列中的子序列模式?从某种意义上说,它类似于正则表达式,但在元素序列之上 更具体地说,我们希望完成此功能 def findPattern(seq: Seq[String], Seq[String]): Seq[Int] = { // find the indices of seq which matches the input pattern. // if the pattern is not found, return Seq.empty. } 例
def findPattern(seq: Seq[String], Seq[String]): Seq[Int] = {
// find the indices of seq which matches the input pattern.
// if the pattern is not found, return Seq.empty.
}
例如,对于以下输入和目标模式:
seq: Seq[String] = Seq("NNS", "VBG", "JJ", "NNS", "IN", "NNP", "NNP")
pattern: String = Seq("VBG", "JJ")
所需输出应为:
Seq(1, 2)
具有相同序列的另一个示例:
pattern: String = Seq("VBG", "?", "NNS")
并且期望的输出应该是
Seq(1, 2, 3)
还有一个例子:
pattern: String = Seq("VBG", "*", "IN")
这将导致:
Seq(1, 2, 3, 4)
旁注:可以使输出Seq[Seq[Int]]
适应多个模式的存在 我认为解析器应该对查找匹配模式更有意义,有一个实现,希望对您有所帮助:
def findPattern(list: List[String], pattern: List[String]): List[List[Int]] = {
def nextPattern(lt: Option[List[(String, Int)]], ps: List[String]): Option[List[(String, Int)]] = {
ps match {
//if only have "*" should return all
case List("*") => lt
//filter whether first str match head, if not return None
case List(head) =>
lt.filter(_.nonEmpty).filter(_.head._1 == head).map(r => {
List(r.head)
})
//minimum match for wildcard for first str
case "*" :: List(last) =>
lt.filter(_.nonEmpty).flatMap(t => {
t.find(_._1 == last).map(i => {
t.takeWhile(_._1 != last) :+ i
})
})
case "*" :: last :: l =>
nextPattern(lt, List("*", last)).flatMap(j => {
nextPattern(lt.map(_.drop(j.size)), l).map(i => {
j ++ i
})
})
//skip fist str
case "?" :: l =>
lt.filter(_.nonEmpty).flatMap(r => {
nextPattern(Some(r.tail), l).map(j => {
r.head :: j
})
})
//match the list first str
case head :: l =>
lt.filter(_.nonEmpty).filter(_.head._1 == head).flatMap(r => {
nextPattern(Some(r.tail), l).map(j => {
r.head :: j
})
})
}
}
//if any is empty, return None
list.isEmpty || pattern.isEmpty match {
case true => List.empty
case false =>
val relevantIndices = list.zipWithIndex.filter(_._1 == pattern.head).map(_._2)
val relevantSublists = relevantIndices.map(list.zipWithIndex.drop)
relevantSublists.map{ sublist =>
nextPattern(Some(sublist), pattern).map(_.map(_._2))
}.filter(_.isDefined).map(_.get)
}
}
测试:
其结果是:
[info] List(List(0, 1))
[info] List(List(0, 1))
[info] List()
[info] List(List(0, 1, 2))
[info] List(List(1, 2, 3))
[info] List(List(2))
[info] List(List(1, 2, 3, 4))
[info] List(List(1, 2, 3, 4, 5, 6))
[info] List()
[info] List()
[info] List(List(0), List(3))
我一点也不清楚为什么?匹配NNS(以及为什么它与位置0不匹配)或为什么*也与中匹配。你能进一步解释一下吗?如果模式是Seq(“VBG”,“?”,“NNS”)
,那么它是有意义的然后是一个元素的通配符,*
表示一个(或零?)或多个。哎呀,这是一个输入错误。修正了。好的,所以你想要一个标准的“glob”样式和一个不同的字母表相匹配。您是否需要在模式中使用文字'*或'?'呢?(也就是说,你是否需要某种形式的逃跑)。一个快速的谷歌搜索结果是:-你需要让它在Seq[A]上工作,不仅仅是字符串,而且看起来很简单。@TheArchetypalPaul的观点很好。正如您所指出的,我们可以为输入定义类型并区分“?”标签和As通配符。很好!这个实施是一个更大项目的一部分吗?@Daniel,不,这个实施是我尝试的。你知道为什么它失败了吗<代码>列表:列表(DT,NN,IN,DT,NNP,NN,VBD,IN,NN,,,DT,NN,NN,VBD,VBN,IN,CD,,,DT,VBG,VBD,NNP,CC,MD,VB,IN,NNP,)模式:列表(IN,NN)
我对代码做了一些小改动,以覆盖一些边缘情况(如上面的示例)和多个模式。你怎么想?是的,你能行。
[info] List(List(0, 1))
[info] List(List(0, 1))
[info] List()
[info] List(List(0, 1, 2))
[info] List(List(1, 2, 3))
[info] List(List(2))
[info] List(List(1, 2, 3, 4))
[info] List(List(1, 2, 3, 4, 5, 6))
[info] List()
[info] List()
[info] List(List(0), List(3))