Reputation: 1591
I have a regular expression like ".*(A20).*|.*(B30).*|C"
.
I would like to write a function its returns A20
or B30
based on the match found.
val regx=".*(A20).*|.*(B30).*".r
"helloA20" match { case regx(b,_) => b; case _ => "" } // A20
"helloB30" match { case regx(b,_) => b; case _ => "" } // null
"C" match { case regx(b,_) => b case _ => "" }
It's returning null because I am not considering the second group. In my actual code, I have a lot of group like that. I would like to return the matched string. Please help me to find a solution.
Upvotes: 1
Views: 1652
Reputation: 2967
You're close:
def extract(s: String) = s match {
case regx(b, _) if b != null => b
case regx(_, b) if b != null => b
case _ => ""
}
extract("helloA20")
res3: String = A20
extract("helloB30")
res4: String = B30
extract("A30&B30")
res6: String = B30
If you have a lot of groups, it's reasonable to use for comprehension insted of pattern matching. This code will return first match or None:
val letters = ('A' to 'Z').toSeq
val regex = letters.map(_.toString).mkString("(", "|", ")").r
def extract(s: String) = {
for {
m <- regex.findFirstMatchIn(s)
} yield m.group(1)
}
extract("A=B=")
extract("dsfdsBA")
extract("C====b")
extract("a====E")
res0: Option[String] = Some(A)
res1: Option[String] = Some(B)
res2: Option[String] = Some(C)
res3: Option[String] = Some(E)
Upvotes: 1
Reputation: 19166
Easy! It should be like this:
val regx="^(.*(B30|A20).*|(C))$".r
Demo: https://regex101.com/r/nA6dQ9/1
Then you get the second value in the array of every group.
That way you only have one group regardless of the many possibilities.
Upvotes: 3