这是一个简单的1-pass解决方案。让我知道它是否足够快。
我不是网址专家,所以可能需要调整。基本上它假设没有未转义的空格,'?','&'或'='字符。
它可以进一步与低级opti平滑。
def extractParams(params: List[String], from: String): Map[String, String] = {
val a = from.toCharArray
val len = a.length
import scala.annotation.tailrec
@tailrec
def extract(p: Set[String], start: Int, results: Map[String, String]): Map[String, String] = {
var paramStart = start
var nextEquals = -1
var nextAmpersand = -1
if (start == 0) { // find start of params
var i = 0
while (i < len && a(i) != '?') {
i += 1
}
if (i == len) return results
paramStart = i
}
{ // find equals
var i = paramStart
while (i < len && a(i) != '=') {
i += 1
}
if (i == len) return results
nextEquals = i
}
{ // find nextAmpersand or end
var i = nextEquals
while (i < len && !(a(i) == '&' || a(i) == ' ')) {
i += 1
}
nextAmpersand = i
}
val paramNameArr = new Array[Char](nextEquals - paramStart - 1)
System.arraycopy(a, paramStart + 1, paramNameArr, 0, nextEquals - paramStart - 1)
val paramName = new String(paramNameArr)
var newResults = results
var newP = p
if (p.contains(paramName)) { // find param value
val paramValueArr = new Array[Char](nextAmpersand - nextEquals - 1)
System.arraycopy(a, nextEquals + 1, paramValueArr, 0, nextAmpersand - nextEquals - 1)
val paramValue = new String(paramValueArr)
newResults = newResults + (paramName -> paramValue)
newP = p - (paramName)
}
if (nextAmpersand == len || a(nextAmpersand) == ' ') { // check for end
return newResults
} else {
return extract(newP, nextAmpersand, newResults)
}
}
extract(params.toSet, "GET ".length, Map.empty)
}
你需要使用正则表达式吗?你能用像split这样的字符串操作方法吗? – 2014-11-14 16:17:32
当你说“大数据集”时,你是什么意思?数百?成千上万的?百万?你有没有尝试过一些东西,发现效率太低了?根据预期的数据集,您可能不需要关心它的有效性。这可能效率不高,但如果你只是想要一组键,我会解析url并生成一个key/value对的映射,提取你感兴趣的对。 – Daenyth 2014-11-14 17:05:51
大到我的意思是数百万行。我曾尝试使用“拆分”,但它需要3倍的时间来运行我的示例。 – user1956609 2014-11-14 17:25:41