首先,我就像酷 ......
scala> var nameRE = """\W*(\w+)\W+(\w+)\W*""".r
nameRE: scala.util.matching.Regex = \W*(\w+)\W+(\w+)\W*
scala> var nameRE(first, last) = "Will Smith "
first: String = Will
last: String = Smith
然后我就像 darn ...
scala> var listOfVowels = "(([aeiou])*)".r
listOfVowels: scala.util.matching.Regex = (([aeiou])*)
scala> var listOfVowels(vowels:List[String]) = "uoiea"
<console>:7: error: scrutinee is incompatible with pattern type;
found : List[String]
required: java.lang.String
var listOfVowels(vowels:List[String]) = "uoiea"
现在我喜欢呵呵 ......
scala> (listOfVowels findFirstMatchIn "uoiea" get) subgroups
res35: List[String] = List(a)
[如果我的问题不明显:我如何得到一个模式实际匹配的所有子组的列表,理想情况是在提取器中,但无论如何都没有编写二级匹配器。这里的正确答案当然是List(u, o, i, e, a)
。 ]
答案 0 :(得分:2)
据我所知,不可能将正则表达式中类型(E)*的子模式转换为字符串列表。这是因为Scala中使用的正则表达式机制是使用JDK的正则表达式的默认实现(java.util.Pattern,java.util.Matcher等)实现的,并且这种实现不支持捕获子模式的多重性。如果匹配,子模式(E)*将仅捕获该子模式的最后一个匹配。据我所知,这种行为甚至适用于大多数正则表达式实现。
虽然我认为您的案例是您实际问题的简化版本,但确实存在一个简单的解决方案:
scala> "[aeiou]".r findAllIn "hello, world!" toList
res1: List[String] = List(e, o, o)
希望这有帮助。
答案 1 :(得分:2)
这将允许您提取模式:
scala> var listOfVowels(vowels @ _*) = "uoiea"
vowels: Seq[String] = List(uoiea, a)
但是,该模式不能达到预期效果 - 它不会生成多个组。正则表达式库规则是一组括号,一组,我知道的每个正则表达式都是这样的。
答案 2 :(得分:1)
这有点风格草率。
scala> implicit def mkRr(regex: String) = new { def rr = new { def unapply(s: String) = (regex.r findAllIn s toList) match { case Nil => None ; case xs => Some(xs) } } }
mkRr: (regex: String)java.lang.Object{def rr: java.lang.Object{def unapply(s: String): Option[List[String]]}}
scala> val ListOfVowels = "[aeiou]".rr
ListOfVowels: java.lang.Object{def unapply(s: String): Option[List[String]]} = $anon$1$$anon$2@49f2afad
scala> val ListOfVowels(vowels) = "uoiea"
vowels: List[String] = List(u, o, i, e, a)