Разбор даты из CharSequence со стандартными шаблонами ... - PullRequest
2 голосов
/ 03 февраля 2011

Я пишу парсер для интерфейса командной строки внешнего инструмента и использую библиотеку комбинаторов парсера Scala. В рамках этого мне нужно разобрать стандартную дату в формате EEE MMM d ЧЧ: мм: сс гггг Z .

Парсер-комбинаторы Scala "основаны на потоке" и работают с CharSequence вместо Strings. Из-за этого мне трудно использовать java.text.DateTimeFormat или DateTimeFormat из JodaTime, поскольку они оба работают со строками.

На данный момент я должен написать свой собственный анализатор регулярных выражений, подобный этому, для разбора даты, но я бы предпочел включить работу, проделанную с JodaTime, в мой анализатор. Я действительно не хочу изобретать велосипед. Я искал исходный код JodaTime, и я не совсем уверен, почему он должен работать со строками, а не только с CharSequence. Я пропускаю какой-то аспект?

Ответы [ 3 ]

1 голос
/ 03 февраля 2011

Понял, сейчас. Хорошо, есть более простое решение, чем разветвление. Здесь:

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))
    }
  }
}
0 голосов
/ 03 февраля 2011

Это мое решение прямо сейчас:

Я раздвоил время joda и внес небольшие изменения, чтобы он работал на CharSequence с вместо 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")

Я переутомляюсь? Я очень устала прямо сейчас ...

0 голосов
/ 03 февраля 2011

Я не уверен, что вы спрашиваете.Вы спрашиваете, почему RegexParser.parse() s in параметр принимает CharSequence?Если это так, есть еще одна перегруженная RegexParser.parse(), которая принимает Reader, и вы можете написать простую функцию преобразования, например, такую:

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

Что касается формата даты, я нахожу, что это прекрасно, определить ее кактокен в парсере.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...