如何在scala中的单词后截断字符串

j3d*_*j3d 5 regex scala

鉴于以下字符串......

"localhost:9000/one/two/three"
Run Code Online (Sandbox Code Playgroud)

我希望在单词之后将其截断two并获取

"localhost:9000/one/two"
Run Code Online (Sandbox Code Playgroud)

我已经实现了这些方法truncateBefore并且truncateAfter像这样:

def truncateBefore(s: String, p: String) = {
  s.substring(s.indexOf(p) + p.length, s.length)
}

def truncateAfter(s: String, p: String) = {
  s.substring(0, s.indexOf(p) + p.length)
}
Run Code Online (Sandbox Code Playgroud)

这些方法起作用并返回预期结果:

scala> truncateAfter("localhost:9000/one/two/three", "two")
res1: String = "localhost:9000/one/two"

scala> truncateBefore("localhost:9000/one/two/three", "two")
res2: String = "/three"
Run Code Online (Sandbox Code Playgroud)

在scala中有更好的方法吗?最好用正则表达式?

yǝs*_*ǝla 6

使用正则表达式的一个选项:

val beforeAfter = "(^.*two)(.*)$".r

scala> val beforeAfter(after, before) = "localhost:9000/one/two/three"
after: String = localhost:9000/one/two
before: String = /three
Run Code Online (Sandbox Code Playgroud)

使用split的另一个选项:

scala> "localhost:9000/one/two/three" split ("two")
res0: Array[java.lang.String] = Array(localhost:9000/one/, /three)
Run Code Online (Sandbox Code Playgroud)

如果您two在输入中没有单词,这些不是超级强大的解决方案,但您可以相应地处理它...

还有一个使用正则表达式进行理解:

scala> val beforeAfter = "(^.*two)(.*)$".r
beforeAfter: scala.util.matching.Regex = (^.*two)(.*)$

scala> (for {
     |   matches <- beforeAfter.findAllIn("localhost:9000/one/two/three").matchData
     |   tokens <- matches.subgroups
     |  } yield tokens).toList
res0: List[String] = List(localhost:9000/one/two, /three)
Run Code Online (Sandbox Code Playgroud)

如果没有匹配,这是安全的:

scala> (for {
     |   match <- beforeAfter.findAllIn("localhost").matchData
     |   token <- match.subgroups
     |  } yield token).toList
res1: List[String] = List()
Run Code Online (Sandbox Code Playgroud)


som*_*ytt 2

在第一个文字之后拆分,没有太多正则表达式(双关语)。

scala> implicit class `split after`(val s: String) {
     | def splitAfter(p: String): (String, String) = {
     |   val r = (Regex quote p).r
     |   r findFirstMatchIn s map (m => (s.substring(0, m.end), m.after.toString)) getOrElse (s, "")
     | }}
defined class split$u0020after

scala> "abcfoodeffooghi" splitAfter "foo"
res2: (String, String) = (abcfoo,deffooghi)

scala> "abc*def" splitAfter "*"
res3: (String, String) = (abc*,def)
Run Code Online (Sandbox Code Playgroud)