Reputation: 13410
There is a very nice way to unpack matched groups from regex:
scala> val regex = "(first):(second)".r
regex: scala.util.matching.Regex = (first):(second)
scala> val regex(a, b) = "first:second"
a: String = first
b: String = second
Unfortunately, this throws exception when there is no match:
scala> val regex(a, b) = "first:third"
scala.MatchError: first:third (of class java.lang.String)
at .<init>(<console>:10)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:744)
In this case I could use findFirstMatchIn
to get None
is there is no match:
scala> val result = regex.findFirstMatchIn("first:third")
result: Option[scala.util.matching.Regex.Match] = None
But in case of match, I want to have something as good as the first variant with unpacking. Now I have to deal with this:
scala> val result = regex.findFirstMatchIn("first:second")
result: Option[scala.util.matching.Regex.Match] = Some(first:second)
What I came up with is this:
scala> val content = result.get
content: scala.util.matching.Regex.Match = first:second
scala> 1 to content.groupCount map content.group
res0: scala.collection.immutable.IndexedSeq[String] = Vector(first, second)
Is there any better way to get all groups from regex match object (ideally as succinct as unpacking in the first code snippet in this question)?
Upvotes: 0
Views: 606
Reputation: 49410
You could use pattern matching
Something along this (untested)
val regex = "(first):(second)".r
val myString = "first:second"
myString match {
case regex(first, second) => do something
case _ => None
}
Upvotes: 1
Reputation: 39577
They came up with Groups
for that:
scala> regex findFirstMatchIn "first:second" map { case Regex.Groups(a,b) => (a,b) }
res8: Option[(String, String)] = Some((first,second))
I think that's the same now as:
scala> regex findFirstMatchIn "first:second" map { case regex(a,b) => (a,b) }
res9: Option[(String, String)] = Some((first,second))
since it doesn't recompute the match.
Upvotes: 3