val p : Regex = ".*no=([0-9]+),name=(.*)".r;
val values = List(
"no=10,name=ten",
"no=11,name=eleven",
"no=20,name=twelve" );
for (value <- values ) {
value match {
case p("10", v) => println("name for 10: " + v)
case p("11", v) => println("name for 11: " + v)
case p(n, v) => println("name, value= " + (n,v))
}
}
name for 10: ten
name for 11: eleven
name, value= (20,twelve)
String#r メソッドで scala.util.matching.Regex オブジェクトを作ることができる。
match ... case 文の case 句で、正規表現中のグループに対する値や変数を指定しておくことで、 比較対象の文字列とマッチさせることができる。
上の例の最初と2つめの case 句では、第一グループに値を指定してマッチした対象の第2グループの値を変数に入れて取り出す。
3番目の case 句では1番目、2番目の case 句でマッチしなかった対象に対して両グループの値を取り出している。
この動作の仕組みを調べてみよう。
Scala の Regex は普通こんな感じで使う。
val p : Regex = """.*no=([0-9]+),name=(.*)""".r;
val s = "no=10,name=ten";
val m : Regex.Match = p.findFirstMatchIn(s).get;
println("no: " + m.group(1))
println("name: " + m.group(2))
no: 10
name: ten
Regex には メンバーメソッドに抽出子 unapplySeq があって文字列を渡すことができる。
val p : Regex = """.*no=([0-9]+),name=(.*)""".r; val s = "no=10,name=ten"; println(p.unapplySeq(s));
Some(List(10, ten))
正規表現を使った match...case 文ではこの抽出子を使ってグループの値を取り出して マッチを行っているものと思う。
Regex の派生クラスを作って、unapplySeq を override して実験。
val p : Regex = new Regex2(""".*no=([0-9]+),name=(.*)""");
val value = "no=10,name=ten";
value match {
case p("10", v) => println("name for 10: " + v)
case p(n, v) => println("name, value= " + (n,v))
}
...
private class Regex2(regex: String) extends Regex(regex) {
override def unapplySeq(target: Any): Option[List[String]] = {
println("Regex2 unapplySeq called.");
return super.unapplySeq(target);
}
}
Regex2 unapplySeq called.
name for 10: ten
確かに Regex の unapplySeq が実行されていることが分かった。
0 件のコメント:
コメントを投稿