在没有正则表达式的情况下,Scala中的Caseinsenstive String替换

时间:2013-12-09 13:46:46

标签: string scala replace

如何在搜索不区分大小写的情况下用'someother'替换任何出现的'something'?所以'SoMETHING'也应该被'someother'替换。

我知道我可以使用正则表达式执行此操作,但出于性能原因(并且因为我不需要任何正则表达式功能),我正在搜索scala中更快捷方便的方法。 scala中有没有?我搜索了一个java解决方案,但我找不到一个......

2 个答案:

答案 0 :(得分:4)

我刚刚写了这个来表明手动操作比正则表达更快...其中正则表达式需要57毫秒,这需要34毫秒。对于任何源长度,它也是完全线性可扩展的。

没有超级优化或任何东西,如果您真的使用它,您可能想要输入一些范围检查以查看错误输入。

  // replace all, case insensitive
  def replace(source: String, target: String, replacement: String): String = {

    // initialize the builder to sufficient size to reduce chance of needing to grow
    val out = new StringBuilder(source.size * 2)
    // last index we need to check for match
    val lastIdx = source.length - target.length
    // simple optimization
    val targetLower = target.toLowerCase

    // check for match at given index, at char offset along target
    @tailrec
    def matches(idx: Int, offset: Int): Boolean =
      if (offset >= target.length) 
        true
      else if(targetLower.charAt(offset) == source.charAt(idx + offset).toLower)
        matches(idx, offset + 1)
      else false

    // search source and append to builder
    @tailrec
    def search(idx: Int): Unit =
      if (idx > lastIdx)
        out.append(source.substring(idx))
      else if (matches(idx, 0)) {
        out.append(replacement)
        search(idx + target.length)
      }
      else {
        out.append(source.charAt(idx))
        search(idx + 1)
      }

    search(0)
    out.toString
  }

答案 1 :(得分:3)

正则表达式通常比使用您自己的实现更快,例如使用StringBuilder。只要您坚持使用标准正则表达式并避免计算密集型功能(例如“向后看”),正则表达式就会非常快。

在我编码的测试中,正则表达式替换比StringBuilder实现快20倍。您可以在这个要点中找到源代码:

https://gist.github.com/tmbo/7889544

我还分析了测试应用程序,并且StringBuilder实施需求花费的时间约为StringBuilder.replace的约75%。