他の回答に示されているように、複数回一致したグループの最後の一致を常に取得します。これは、基盤となる Java 正規表現エンジンの制限です。
あなたの場合、最初に値を分割し、個々のグループを評価する方が良いかもしれません:
scala> val nameSeparator="""\.""".r
nameSeparator: scala.util.matching.Regex = \.
scala> val namePart="""[a-z]+""".r
namePart: scala.util.matching.Regex = [a-z]+
scala> val parts=nameSeparator.split("abc.def.ghi")
parts: Array[String] = Array(abc, def, ghi)
scala> parts.forall(!namePart.unapplySeq(_).isEmpty)
res20: Boolean = true
最後の式は、配列部分のすべての要素が正規表現 namePart に一致するかどうかをチェックします。
より複雑な問題がある場合 (たとえば、式がプレフィックスで始まり、異なるセパレーターを持つ複数のグループがあり、その後にサフィックスが続く) は、パーサー コンビネーターに直接切り替える方がよい場合があります。
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.util.parsing.combinator.RegexParsers
object NameParser extends RegexParsers {
def separator : Parser[String] = """\.""".r
def namePart : Parser[String] = """[a-z]+""".r
def name : Parser[List[String]] = repsep(namePart, separator)
def apply(input: String) = parseAll(name, input)
}
// Exiting paste mode, now interpreting.
import scala.util.parsing.combinator.RegexParsers
defined module NameParser
scala> NameParser("abc.def.ghi")
res24: NameParser.ParseResult[List[String]] = [1.12] parsed: List(abc, def, ghi)
この例は、より複雑なパーサーに簡単に適用できます。また、エラー処理が必要な場合は、パーサー コンビネーターを正規表現よりも簡単に拡張できます。