是否有Scala库API方法(如果不是,这是一种惯用的方法)来获取更大字符串(源)中子字符串(目标)的所有索引的列表?我试图浏览ScalaDoc,但无法找到任何明显的东西。有很多方法可以做很多有用的事情,我猜我只是没有提交正确的搜索词。
例如,如果我的源字符串为“name:Yo,name:Jim,name:name,name:bozo”,我使用目标字符串“name:”,我想找回一个List列表的[Int](0,8,17,27)。
这是我快速解决问题的方法:
def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = {
def recursive(index: Int, accumulator: List[Int]): List[Int] = {
if (!(index < source.size)) accumulator
else {
val position = source.indexOf(target, index)
if (position == -1) accumulator
else {
recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator)
}
}
}
if (target.size <= source.size) {
if (!source.equals(target)) {
recursive(0, Nil).reverse
}
else List(0)
}
else Nil
}
任何指导都可以让我用适当的标准库入口点替换它,我们将不胜感激。
更新2014 / Jul / 22:
受Siddhartha Dutta的回答启发,我加强了我的代码。它现在看起来像这样:
def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = {
@tailrec def recursive(indexTarget: Int, accumulator: List[Int]): List[Int] = {
val position = source.indexOf(target, indexTarget)
if (position == -1) accumulator
else
recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator)
}
recursive(index, Nil).reverse
}
另外,如果我有一个源代码字符串“aaaaaaaa”并使用目标字符串“aa”,我希望默认情况下返回List的列表[Int](0,2,4,6)从已找到的子字符串开始跳过搜索。默认值可以通过为“aaaaaaa”/“aa”情况下返回List(0,1,2,3,4,5,6)的withinOverlaps参数传递“true”来覆盖。
答案 0 :(得分:6)
我总是倾向于接触到像这样的问题的正则表达式技巧。我不会说它是正确的,但这是一个很少的代码。 :)
val r = "\\Qname\\E".r
val ex = "name:Yo,name:Jim,name:name,name:bozo"
val is = r.findAllMatchIn(ex).map(_.start).toList
对于这种情况,引号\\Q
和\\E
不是必需的,但如果您要查找的字符串有任何特殊字符,那么它就是。
答案 1 :(得分:1)
获取所有索引的小代码
将以下方法称为getAllIndexes(source,target)
def getAllIndexes(source: String, target: String, index: Int = 0): List[Int] = {
val targetIndex = source.indexOf(target, index)
if(targetIndex != -1)
List(targetIndex) ++ getAllIndexes(source, target, targetIndex+1)
else
List()
}