2

私は外部ツールのコマンドラインインターフェイス用のパーサーを作成しており、Scalaのパーサーコンビネーターライブラリを使用しています。この一環として、EEE MMM d HH:mm:ssyyyyZ形式の標準日付を解析する必要があります。

Scalaのパーサーコンビネーターは「ストリームベース」であり、Stringsの代わりにCharSequenceで動作します。JodaTimeのjava.text.DateTimeFormatまたはDateTimeFormatはどちらも文字列で機能するため、どちらも使用するのが難しくなります。

今のところ、日付を解析するためにこのような独自の正規表現パーサーを作成する必要がありましたが、JodaTimeで行われた作業をパーサーに組み込む方がはるかに望ましいです。私は本当に車輪の再発明をしたくありません。私はJodaTimeのソースコードを見てきましたが、CharSequencesだけでなくStringsで動作する必要がある理由がよくわかりません。私はいくつかの側面が欠けていますか?

4

3 に答える 3

1

了解しました。わかりました、フォークよりも簡単な解決策があります。ここ:

trait DateParsers extends RegexParsers {
  def dateTime(pattern: String): Parser[DateTime] = new Parser[DateTime] {
    val dateFormat = DateTimeFormat.forPattern(pattern);

    def jodaParse(text: CharSequence, offset: Int) = {
      val mutableDateTime = new MutableDateTime
      val maxInput = text.source.subSequence(offset, dateFormat.estimateParsedLength + offset).toString
      val newPos = dateFormat.parseInto(mutableDateTime, maxInput, 0)
      (mutableDateTime.toDateTime, newPos + offset)
    }

    def apply(in: Input) = {
      val source = in.source
      val offset = in.offset
      val start = handleWhiteSpace(source, offset)
      val (dateTime, endPos) = jodaParse(source, start)
      if (endPos >= 0)
        Success(dateTime, in.drop(endPos - offset))
      else
        Failure("Failed to parse date", in.drop(start - offset))
    }
  }
}
于 2011-02-03T14:20:36.850 に答える
0

あなたが何を求めているのかわかりません。RegexParser.parse()inパラメータがなぜかかるのか疑問に思っていますCharSequenceか?もしそうなら、次のような単純な変換関数を書くことができる、をRegexParser.parse()とる別のオーバーロードがあります:Reader

def stringToReader(str: String): Reader = new StringReader(str)

日付形式に関しては、パーサーでトークンとして定義するのはまったく問題ありません。

お役に立てれば。

于 2011-02-03T14:37:14.050 に答える
0

これが今の私の解決策です:

joda-timeをフォークし、CharSequencesではなくsで動作するように小さな変更を加えましたString。ここにありますhttps://github.com/hedefalk/joda-time/commit/ef3bdafd89b334fb052ce0dd192613683b3486a4

それから私はこのように書くことができますDateParser

trait DateParsers extends RegexParsers {
  def dateTime(pattern: String): Parser[DateTime] = new Parser[DateTime] {
    val dateFormat = DateTimeFormat.forPattern(pattern);

    def jodaParse(text: CharSequence, offset: Int) = {
      val mutableDateTime = new MutableDateTime
      val newPos = dateFormat.parseInto(mutableDateTime, text, offset)
      (mutableDateTime.toDateTime, newPos)
    }

    def apply(in: Input) = {
      val source = in.source
      val offset = in.offset
      val start = handleWhiteSpace(source, offset)
      val (dateTime, endPos) = jodaParse(source, start)
      if (endPos >= 0)
        Success(dateTime, in.drop(endPos - offset))
      else
        Failure("Failed to parse date", in.drop(start - offset))
    }
  }
}

次に、このトレイトを使用して、次のようなプロダクションルールを作成できます。

private[this] def dateRow = "date:" ~> dateTime("EEE MMM d HH:mm:ss yyyy Z")

私はこれを酷使していますか?今は本当に疲れています…</p>

于 2011-02-03T14:45:44.810 に答える