smeeb
smeeb

Reputation: 29567

Extracting inner group with Scala regex

My Scala app is being given a string that may or may not contain the token "flimFlam(*)" inside of it, where the asterisk represents any kind of text, chars, punctuation, etc. There will always only be 0 or 1 instances of "flimFlam(*)" in this string, never more.

I need to detect if the given input string contains a "flimFlam(*)" instance, and if it does, extract out whatever is inside the two parentheses. Hence, if my string contains "flimFlam(Joe)", then the result would be a string with a value of "Joe", etc.

My best attempt so far:

val inputStr : String = "blah blah flimFlam(Joe) blah blah"

// Regex must be case-sensitive for "flimFlam" (not "FLIMFLAM", "flimflam", etc.)
val flimFlamRegex = ".*flimFlam\\(.*?\\)".r
val insideTheParens = flimFlamRegex.findFirstIn(inputStr)

Can anyone spot where I'm going awry?

Upvotes: 0

Views: 275

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627449

You may use a capturing group around .*? and just use an unanchored regex within match block so that the pattern could stay short and "pretty" (no need for .* around the value you are looking for):

var str = "blah blah flimFlam(Joe) blah blah"
val pattern = """flimFlam\((.*?)\)""".r.unanchored
val res = str match {
   case pattern(res) => println(res)
   case _ => "No match"
}

See the online demo

Also, note that you do not need to double backslashes inside """-quoted string literals that helps avoid excessive backslashes.

And a hint: if the flimFlam is a whole word, add \b in front - """\bflimFlam\((.*?)\)""".

Upvotes: 0

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Use pattern matching and regex extractor

val regex = ".*flimFlam\\((.*)\\).*".r

inputStr match { 
 case regex(x) => println(x)
 case _ => println("no match")
}

Scala REPL

scala> val inputStr : String = "blah blah flimFlam(Joe) blah blah"
inputStr: String = blah blah flimFlam(Joe) blah blah

scala> val regex = ".*flimFlam\\((.*)\\).*"
regex: String = .*flimFlam\((.*)\).*

scala> val regex = ".*flimFlam\\((.*)\\).*".r
regex: scala.util.matching.Regex = .*flimFlam\((.*)\).*

scala> inputStr match { case regex(x) => println(x); case _ => println("no match")}
Joe

Upvotes: 2

Related Questions