我试图在scala中获取逗号分隔字符串的前2个值。例如
a,b,this is a test
如何将值a,b存储在2个单独的变量中?
答案 0 :(得分:7)
保持简单和干净。
KISS解决方案:
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*
答案 1 :(得分:4)
Scala enter link description here
中使用Sequence Pattern match
的另一种解决方案
Welcome to Scala version 2.11.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val str = "a,b,this is a test"
str: String = a,b,this is a test
scala> val Array(x, y, _*) = str.split(",")
x: String = a
y: String = b
scala> println(s"x = $x, y = $y")
x = a, y = b
答案 2 :(得分:3)
您在寻找方法split
吗?
"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))
答案 3 :(得分: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)
如果记录是长字符串,这会更好。
脚注:选项案例看起来更好regex interpolator.
答案 4 :(得分:0)
如果您的字符串很短,您也可以使用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"
当然,您可以将正则表达式调整为仅允许非空标记(或您可能需要验证的任何其他内容):
val regex = """(.+),(.+),.+""".r
请注意,在我的示例中,我假设字符串始终至少有两个令牌。在第一个示例中,您可以根据需要测试数组的长度。如果正则表达式与字符串不匹配,则第二个将抛出MatchError。
我最初提出了以下解决方案。我将保留它,因为它有效,并且不使用任何正式标记为已弃用的类,但StringTokenizer的Javadoc提到它是遗留类,不应再使用。
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