Reputation: 574
I have a string, say var str = "hello, world"
and a List
of Regex
patterns
val patterns = List(new Regex("hello, (.*)", "substr"), new Regex("hi, (.*)", "substr"))
How can I match str
against these patterns? Now instead of using List
of patterns I'm doing the following:
val pattern1 = new Regex("hello, (.*)", "substr")
val pattern2 = new Regex("hi, (.*)", "substr")
var someVar = "something"
var someVar2 = "something else"
str match {
case pattern1(substr) => { someVar = substr; someVar2 = "someValue" }
case pattern2(substr) => { someVar = substr; someVar2 = "someOtherValue" }
}
Appendix:
I forgot to mention one important thing: in fact there are several lists of patterns. And someVar2 takes its value depending on the list from which the first pattern match occurred. It does not matter for me whether to use nested lists like List(List(new Regex(...), new Regex(...), ...), List(new Regex(...), new Regex(...), ...))
or to use separate val
for each list of patterns like val patterns1 = List(new Regex(...), ...); val patterns2 = List(new Regex(...), ...)
.
Upvotes: 2
Views: 3798
Reputation: 15074
Try this:
scala> patterns.collectFirst{ p => str match { case p(substr) => substr } }
res3: Option[String] = Some(world)
scala> val str2 = "hi, Fred"
str2: String = hi, Fred
scala> patterns.collectFirst{ p => str2 match { case p(substr) => substr } }
res4: Option[String] = Some(Fred)
EDIT: updating to account for changed requirements...
Given:
val patternMapping = Map(("marker1" -> patterns), ("marker2" -> patterns2), ...)
You should be able to nest the collectFirst calls, resulting in something like this:
scala> patternMapping.collectFirst{ case (mark, pList) => pList.collectFirst{ p => str match { case p(substr) => (mark -> substr) } } }.flatten
res5: Option[(String, String)] = Some((marker1,world))
I suspect this could probably be played around with and neatened up, but should give the general idea.
Upvotes: 7
Reputation: 31724
Well you yourself solved it. There are many ways. One of the idiomatic way is:
val patterns = List(new Regex("hello, (.*)", "substr"), new Regex("hi, (.*)", "substr"))
patterns.foreach{ x =>
str match {
case x(substr) => { someVar = substr; someVar2 = "defaultValue" }
case _ => ;
}
}
In case, if you wish to replace defaultValue
with the index of regex it matched then:
val i = patterns.zipWithIndex
i.foreach{ x =>
str match {
case x._1(substr) => { someVar = substr; someVar2 = "defaultValue - "+x._2 }
case _ => ;
}
}
Upvotes: 3