如何在Scala中将字符串中的相似字符分组?

时间:2018-12-10 17:44:12

标签: regex scala

假设我有这样的字符串:

val a = "aaaabbbcccss"

并且我想这样仅将a和b分组:

"a4b3cccss"

我尝试了a.toList.groupBy(identity).mapValues(_.size),但返回的地图没有排序,因此我无法将其转换为所需的形式。我想知道scala中是否有可以实现我想要的功能?

2 个答案:

答案 0 :(得分:3)

您可以使用

val a = "aaaabbbcccss"
val p = """([ab])\1*""".r
println(p replaceAllIn (a, m => s"${m.group(1)}${m.group(0).size}") )

请参见Scala demo

正则表达式匹配:

  • ([ab])-第1组:ab
  • \1*-捕获到第1组的char出现零次或多次。

在替换部分中,m.group(1)是捕获到组1中的字符,m.group(0).size是整个比赛的大小。

答案 1 :(得分:1)

作为替代方法,您可以创建一个函数,该函数可以提供字符串和字符列表,并使用递归方法,其中可以使用takeWhile从列表中获取连续的字符。

然后使用takewhile的结果长度从列表中删除,然后将要连接的内容添加到acc字符串中,当列表为空时将返回该字符串。

def countSimilar(str: String, ch: List[Char]): String = {
  def process(l: List[Char], acc: String = ""): String = {
    l match {
      case Nil => acc
      case h :: _ =>
        val tw = l.takeWhile(_ == h)
        acc + process(
          l.drop(tw.length),
          if (ch.contains(h)) h + tw.length.toString else tw.mkString("")
        )
    }
  }

  process(str.toList)
}

println(countSimilar("aaaabbbcccss", List('a', 'b')))
println(countSimilar("aaaabbbcccssaaaabb", List('a', 'b', 'c')))

这将为您提供:

a4b3cccss
a4b3c3ssa4b2

请参见Scala demo