Scala 获取逗号分隔字符串中的前2个值

Scala 获取逗号分隔字符串中的前2个值,scala,Scala,我试图在scala中获取逗号分隔字符串的前2个值。比如说 a,b,this is a test 如何将值a、b存储在两个单独的变量中?您正在寻找拆分方法吗 "a,b,this is a test".split(',') res0: Array[String] = Array(a, b, this is a test) 如果只需要前两个值,则需要执行以下操作: val splitted = "a,b,this is a test".split(',') val (first, second)

我试图在scala中获取逗号分隔字符串的前2个值。比如说

a,b,this is a test

如何将值a、b存储在两个单独的变量中?

您正在寻找拆分方法吗

"a,b,this is a test".split(',')
res0: Array[String] = Array(a, b, this is a test)
如果只需要前两个值,则需要执行以下操作:

val splitted = "a,b,this is a test".split(',')
val (first, second) = (splitted(0), splitted(1))

保持它的简单和干净

接吻解决方案:

1.使用拆分进行分离。然后使用在所有有序序列上定义的获取,以根据需要获取元素:

scala> val res = "a,b,this is a test" split ',' take 2
res: Array[String] = Array(a, b)
2.使用模式匹配设置变量:

scala> val Array(x,y) = res
x: String = a
y: String = b*

如果您的字符串很短,您也可以使用
string.split
并获取前两个元素

val myString = "a,b,this is a test"
val splitString = myString.split(',') // Scala adds a split-by-character method in addition to Java's split-by-regex
val a = splitString(0)
val b = splitString(1)
另一种解决方案是使用正则表达式提取前两个元素。我觉得它很优雅

val myString = "a,b,this is a test"
val regex = """(.*),(.*),.*""".r    // all groups (in parenthesis) will be extracted.
val regex(a, b) = myString          // a="a", b="b"
当然,您可以调整正则表达式,使其仅允许非空令牌(或您可能需要验证的任何其他令牌):

注意,在我的示例中,我假设字符串总是至少有两个标记。在第一个示例中,如果需要,可以测试数组的长度。如果正则表达式与字符串不匹配,则第二个将抛出MatchError


我最初提出了以下解决方案。我将离开它,因为它可以工作并且不使用任何正式标记为不推荐的类,但是Javadoc for提到它是一个遗留类,不应该再使用

val myString = "a,b,this is a test"
val st = new StringTokenizer(",");
val a = st.nextToken()
val b = st.nextToken()
// You could keep calling st.nextToken(), as long as st.hasMoreTokens is true

在Scala中使用序列模式匹配的另一种解决方案


这里应该有一些正则表达式选项

scala> val s = "a,b,this is a test"
s: String = a,b,this is a test

scala> val r = "[^,]+".r
r: scala.util.matching.Regex = [^,]+

scala> r findAllIn s
res0: scala.util.matching.Regex.MatchIterator = non-empty iterator

scala> .toList
res1: List[String] = List(a, b, this is a test)

scala> .take(2)
res2: List[String] = List(a, b)

scala> val a :: b :: _ = res2
a: String = a
b: String = b
但是

或者,如果您不确定是否有第二项,例如:

scala> val r2 = "([^,]+)(?:,([^,]*))?".r.unanchored
r2: scala.util.matching.UnanchoredRegex = ([^,]+)(?:,([^,]*))?

scala> val (a,b) = "a" match { case r2(x,y) => (x, Option(y)) }
a: String = a
b: Option[String] = None

scala> val (a,b) = s match { case r2(x,y) => (x, Option(y)) }
a: String = a
b: Option[String] = Some(b)
如果记录是长字符串,这会更好一些


脚注:带有

的选项用例看起来更漂亮。您是否看到其中的部分:StringTokenizer是一个遗留类,出于兼容性原因保留了它,尽管新代码中不鼓励使用它。实际上,我没有看到。我想这意味着一个合适的解决方案将使用正则表达式-我将用一个来编辑我的答案。你不需要这样做。请参阅作业左侧的惯用模式的其他答案。如果字符串中的元素少于2个,该怎么办?
scala> val s = "a,b,this is a test"
s: String = a,b,this is a test

scala> val r = "[^,]+".r
r: scala.util.matching.Regex = [^,]+

scala> r findAllIn s
res0: scala.util.matching.Regex.MatchIterator = non-empty iterator

scala> .toList
res1: List[String] = List(a, b, this is a test)

scala> .take(2)
res2: List[String] = List(a, b)

scala> val a :: b :: _ = res2
a: String = a
b: String = b
scala> val a :: b :: _ = (r findAllIn "a" take 2).toList
scala.MatchError: List(a) (of class scala.collection.immutable.$colon$colon)
  ... 33 elided
scala> val r2 = "([^,]+)(?:,([^,]*))?".r.unanchored
r2: scala.util.matching.UnanchoredRegex = ([^,]+)(?:,([^,]*))?

scala> val (a,b) = "a" match { case r2(x,y) => (x, Option(y)) }
a: String = a
b: Option[String] = None

scala> val (a,b) = s match { case r2(x,y) => (x, Option(y)) }
a: String = a
b: Option[String] = Some(b)