2016-11-15 5 views
1

ファイルをスキャンして、の最初のインスタンスの正規表現を見つけて、その式に一致するグループの値を返します。Regexのグループとストリームを組み合わせてファイルを検索する方法

これまでの私の主張は、非常に扱いにくく、正規表現を繰り返し使用するように見えましたが、一度ターゲット文字列を見つけて再びグループを取得しました。私はRegexpの始めと終わりに。*を使うのも好きではありません。

誰でもこれを行うためのよりエレガントな方法を提案できますか?

val DateRegexp = """.*(\d\d\d\d)-(\d\d)-(\d\d).*""".r 
    val lineWithDate = scala.io.Source.fromFile(filenameGC).getLines().find{_.matches(""".*(\d\d\d\d)-(\d\d)-(\d\d).*""") } 
    lineWithDate match { 
    case Some(result) => 
     result match { 
     case DateRegexp(year, month, day) => 
      println(year, month, day) 
     } 
    case None => 
     println("No date found in file") 
    } 

シリルCorpetから大きな入力した後、私は今...

val DateRegexp = """(\d\d\d\d)-(\d\d)-(\d\d)""".r.unanchored 
scala.io.Source.fromFile(filenameGC).getLines().collectFirst{ 
        case DateRegexp(y, m, d) => println(y, m, d)} 

答えて

1

Regexが既に(パターンマッチングの意味での)パターンでいるので、あなたがあなたのcase文で直接使用することができます:

fileString match { 
    case DateRegexp(year, month, day) => println(year, month, day) 
} 

しかし、あなたの場合には、.*は貪欲であること、それはあなたの文字列のパターンの最後の発生をキャッチします。

ありがとうございます。unanchored(パターン全体が文字列と一致しないことを意味します)と指定すると、パターンの先頭と末尾にある.*を削除できます。貪欲*がなければ、あなたは今、最初の発生をキャッチ:

val regex = """(\d\d\d\d)-(\d\d)-(\d\d)""".r.unanchored 

"1987-05-18 2002-12-14" match { 
    case regex(y, m, d) => (y.toInt, m.toInt, d.toInt) // (1987, 5, 18) 
} 

EDITを:私はあなたがStringが、Seq[String]を持っていないということです質問の最初の問題に対処していない実現しました。しかし、一度線の抽出をしたら、最初の関連するものまでのすべての行にcollectFirstを使用するだけでよいので、与えられたcaseの1つに一致する最初のオカレンスを見つけて何かをします:

(lines: List[String]).collectFirst{ 
    case regex(y, m, d) => println(y, m, d) 
} 
+0

完璧、多くのありがとうございます。 – BarneyW

+0

ようこそ。私はあなたの質問に答える前に 'unanchored'について知らなかったので、私はこれを発見して嬉しかったです。 –

関連する問題