[英]Scala: matching a String against a List of Regex
I have a string, say var str = "hello, world"
and a List
of Regex
patterns 我有一个字符串,比如
var str = "hello, world"
和一个正则Regex
List
val patterns = List(new Regex("hello, (.*)", "substr"), new Regex("hi, (.*)", "substr"))
How can I match str
against these patterns? 我怎样才能将
str
与这些模式相匹配? Now instead of using List
of patterns I'm doing the following: 现在,我没有使用模式
List
,而是执行以下操作:
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.
并且someVar2取决于发生第一个模式匹配的列表而取其值。 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(...), ...)
对我来说,使用嵌套列表如
List(List(new Regex(...), new Regex(...), ...), List(new Regex(...), new Regex(...), ...))
或为每个模式列表使用单独的val
,如val patterns1 = List(new Regex(...), ...); val patterns2 = List(new Regex(...), ...)
val patterns1 = List(new Regex(...), ...); val patterns2 = List(new Regex(...), ...)
. val patterns1 = List(new Regex(...), ...); val patterns2 = List(new Regex(...), ...)
。
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: 你应该能够嵌套collectFirst调用,结果是这样的:
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. 我怀疑这可能会被玩弄和整理,但应该给出一般的想法。
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: 如果您希望将
defaultValue
替换为匹配的正则表达式索引,则:
val i = patterns.zipWithIndex
i.foreach{ x =>
str match {
case x._1(substr) => { someVar = substr; someVar2 = "defaultValue - "+x._2 }
case _ => ;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.