regex
  • scala
  • regex-group
  • 2017-07-25 4 views 2 likes 
    2

    日付でなければならないが許容されない形式の文字列の一部を置き換えようとしています。具体的には、日付はすべて「mm/dd/YYYY」の形式であり、「YYYY-mm-dd」の形式である必要があります。 1つの注意点は、元の日付が正確にのがmm/dd/YYYY形式でないことです。 「2015年5月5日」のようなものもあります。例えば、スカラ正規表現を追加の書式で検索/置換する

    val x = "where date >= '05/06/2017'" 
    

    次いで

    x.replaceAll("'([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})'", "'$3-$1-$2'") 
    

    は、所望の置換(復帰 "2017年5月6日")を実行する場合、しかし

    val y = "where date >= '5/6/2017'" 
    

    ため、これは、所望の置換を返しません( "2017-5-6" - 私にとっては無効な表現です)。ジョダ時間ラッパーnscala-timeで、私は日付をキャプチャしようとしたし、それらを再フォーマットしました:

    import com.github.nscala_time.time.Imports._ 
    import org.joda.time.DateTime 
    
    val f = DateTimeFormat.forPattern("yyyy-MM-dd") 
    y.replaceAll("'([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})'", 
        "'"+f.print(DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime("$1"))+"'") 
    

    をしかし、これはjava.lang.IllegalArgumentException: Invalid format: "$1"で失敗します。私はまた、fの補間と0の埋め込みを試してみましたが、どちらかが好きではないようです。

    replaceAll内のキャプチャされたグループ($1など)で追加の処理を実行できませんか。もしそうでなければ、どうすれば希望の結果を得ることができますか?

    答えて

    2

    逆参照のような$1は、文字列置換パターン内でのみ使用できます。あなたのコードでは、"$1"はもはや逆参照ではありません。

    あなたが実際にマッチオブジェクトを取得するにはreplaceAllInで「コールバック」を使用し、さらにそれらを操作するために、そのグループにアクセスすることができます。

    val pattern = "'([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})'".r 
    y = pattern replaceAllIn (y, m => "'"+f.print(DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime(m.group(1)))+"'") 
    
    1

    Regex.replaceAllInはオーバーロードされ、Match => Stringをとることができます。

    関連する問題