从提取器中获取列表 - 甚至是匹配

时间:2010-12-21 08:41:58

标签: regex scala

首先,我就像 ......

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)。 ]

3 个答案:

答案 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)