1

在 URL 包含来自其他系统的源引用的内部网站上工作。这是业务需求,无法更改。即“ http://localhost:9000/source.address.com/7808/project/repo ”“ http://localhost:9000/build.address.com/17808/project/repo

我需要使用特征从“项目/回购”字符串/变量中删除这些字符串,以便可以从多个服务中本地使用。我还希望能够将更多源添加到此列表(已存在)而不修改方法。

“def normalizePath”是服务访问的方法,到目前为止2次非理想但合理的尝试。卡在使用 foldLeft 上,我希望得到一些帮助或更简单的方法来完成所描述的操作。下面的代码示例。

第一次尝试使用 if-else(不理想,因为需要在行下添加更多 if/else 语句并且比模式匹配更易读)

trait NormalizePath {
    def normalizePath(path: String): String = {
        if (path.startsWith("build.address.com/17808")) {
            path.substring("build.address.com/17808".length, path.length)
        } else {
            path
        }
    }
}

和第二次尝试(不理想,因为可能会添加更多模式并且它生成比 if/else 更多的字节码)

trait NormalizePath {
    val pattern = "build.address.com/17808/"
    val pattern2 = "source.address.com/7808/"
    def normalizePath(path: String) = path match {
        case s if s.startsWith(pattern) => s.substring(pattern.length, s.length)
        case s if s.startsWith(pattern2) => s.substring(pattern2.length, s.length)
        case _ => path
    }
}

最后一次尝试是使用地址列表(在其他地方已经存在,但在此处定义为 MWE)从路径字符串中删除出现,但它不起作用:

trait NormalizePath {
    val replacements = (
        "build.address.com/17808",
        "source.address.com/7808/")

    private def remove(path: String, string: String) = {
        path-string
    }

    def normalizePath(path: String): String = {
        replacements.foldLeft(path)(remove)
    }
}   

感谢您对此的任何帮助!

4

3 回答 3

3

如果您只是剥离这些字符串:

val replacements = Seq(
  "build.address.com/17808",
  "source.address.com/7808/")


replacements.foldLeft("http://localhost:9000/source.address.com/7808/project/repo"){
  case(path, toReplace) => path.replaceAll(toReplace, "")
}
// http://localhost:9000/project/repo

如果您将这些字符串替换为其他内容:

val replacementsMap = Seq(
  "build.address.com/17808" -> "one",
  "source.address.com/7808/" -> "two/")


replacementsMap.foldLeft("http://localhost:9000/source.address.com/7808/project/repo"){
  case(path, (toReplace, replacement)) => path.replaceAll(toReplace, replacement)
}
// http://localhost:9000/two/project/repo

集合可以来自代码中的replacements其他地方,不需要重新部署。

// method replacing by empty string
def normalizePath(path: String) = {
  replacements.foldLeft(path){
    case(startingPoint, toReplace) => startingPoint.replaceAll(toReplace, "")
  }
}

normalizePath("foobar/build.address.com/17808/project/repo")
// foobar/project/repo

normalizePath("whateverPath")
// whateverPath

normalizePath("build.address.com/17808build.address.com/17808/project/repo")
// /project/repo
于 2018-03-28T15:28:27.363 回答
2

在 Scala中有一百万零一种/project/repo从字符串中提取的方法。以下是我想出的一些:


val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
  path.stripPrefix(list.find(x => path.contains(x)).getOrElse(""))
}

输出:

scala> normalizePath("build.address.com/17808/project/repo")
res0: String = /project/repo

val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
  list.map(x => if (path.contains(x)) {
    path.takeRight(path.length - x.length)
  }).filter(y => y != ()).head
}

输出:

scala> normalizePath("build.address.com/17808/project/repo")
res0: Any = /project/repo

val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
  list.foldLeft(path)((a, b) => a.replace(b, ""))
}

输出:

scala> normalizePath("build.address.com/17808/project/repo")
res0: String = /project/repo

真的,这取决于您希望代码看起来有多复杂(或者您想要变得多么愚蠢)。请注意,第二个示例具有 return type Any,这可能不适合您的场景。此外,这些示例并不意味着能够仅将字符串从您的中间取出path......如果您想这样做,它们可以相当容易地修改。让我知道您是否希望我添加一些示例,只是从字符串中删除诸如此类build.address.com/17808的内容-我很乐意这样做。

于 2018-03-28T15:39:56.223 回答
1

可以进行如下非常简单的替换:

val replacements = Seq(
  "build.address.com/17808",
  "source.address.com/7808/")

def normalizePath(path: String): String = {
  replacements.find(path.startsWith(_)) // find the first occurrence
              .map(prefix => path.substring(prefix.length)) // remove the prefix
              .getOrElse(path) // if not found, return the original string
}

由于预期的替换非常相似,您是否尝试过概括它们并使用正则表达式匹配?

于 2018-03-28T15:24:24.283 回答