23

有谁知道可以让我解析 .PO 文件的 Java 库?我只是想创建一个 ID 和值的映射,以便可以将它们加载到数据库中。

4

6 回答 6

12

我搜索了互联网,也找不到现有的图书馆。如果您使用 Scala,由于其解析器组合器功能,您自己编写解析器非常容易。

打电话PoParser.parsePo("po file content")。结果是一个列表Translation

我已经把这段代码变成了一个库(任何 JVM 语言都可以使用,当然包括 Java!): https ://github.com/ngocdaothanh/scaposer

import scala.util.parsing.combinator.JavaTokenParsers

trait Translation

case class SingularTranslation(
  msgctxto: Option[String],
  msgid:    String,
  msgstr:   String) extends Translation

case class PluralTranslation(
  msgctxto:    Option[String],
  msgid:       String,
  msgidPlural: String,
  msgstrNs:    Map[Int, String]) extends Translation

// http://www.gnu.org/software/hello/manual/gettext/PO-Files.html
object PoParser extends JavaTokenParsers {
  // Removes the first and last quote (") character of strings
  // and concats them.
  private def unquoted(quoteds: List[String]): String =
    quoteds.foldLeft("") { (acc, quoted) =>
      acc + quoted.substring(1, quoted.length - 1)
    }

  // Scala regex is single line by default
  private def comment = rep(regex("^#.*".r))

  private def msgctxt = "msgctxt" ~ rep(stringLiteral) ^^ {
    case _ ~ quoteds => unquoted(quoteds)
  }

  private def msgid = "msgid" ~ rep(stringLiteral) ^^ {
    case _ ~ quoteds => unquoted(quoteds)
  }

  private def msgidPlural = "msgid_plural" ~ rep(stringLiteral) ^^ {
    case _ ~ quoteds => unquoted(quoteds)
  }

  private def msgstr = "msgstr" ~ rep(stringLiteral) ^^ {
    case _ ~ quoteds => unquoted(quoteds)
  }

  private def msgstrN = "msgstr[" ~ wholeNumber ~ "]" ~ rep(stringLiteral) ^^ {
    case _ ~ number ~ _ ~ quoteds => (number.toInt, unquoted(quoteds))
  }

  private def singular =
    (opt(comment) ~ opt(msgctxt) ~
     opt(comment) ~ msgid ~
     opt(comment) ~ msgstr ~ opt(comment)) ^^ {
    case _ ~ ctxto ~ _ ~ id ~ _ ~ s ~ _ =>
      SingularTranslation(ctxto, id, s)
  }

  private def plural =
    (opt(comment) ~ opt(msgctxt) ~
     opt(comment) ~ msgid ~
     opt(comment) ~ msgidPlural ~
     opt(comment) ~ rep(msgstrN) ~ opt(comment)) ^^ {
    case _ ~ ctxto ~ _ ~ id ~ _ ~ idp ~ _ ~ tuple2s ~ _ =>
      PluralTranslation(ctxto, id, idp, tuple2s.toMap)
  }

  private def exp = rep(singular | plural)

  def parsePo(po: String): List[Translation] = {
    val parseRet = parseAll(exp, po)
    if (parseRet.successful) parseRet.get else Nil
  }
}
于 2011-09-05T10:23:35.390 回答
11

根据Java gettext 实用程序手册,您可以使用程序将 PO 文件转换为 ResourceBundle 类msgfmt --java2,并使用 java.util.ResourceBundle 或 gnu.gettext.GettextResource 读取它——我认为这是一种最有效的方式。Gettext-commons执行完全相同的操作,包括创建中间进程以调用 msgfmt,因为它的位置如下:

Gettext Commons 是使用GNU gettext 实用程序的 Java 库。

如果您仍然想要一个 Java 库,那么我看到的唯一方法是编写自己的库来解析这种格式,即将 msgfmt 源代码从 C 语言重写为 Java 语言。但我不确定它会比创建进程 + 运行 C 程序更快。

于 2011-01-19T23:21:38.697 回答
5

gettext-commons是我在一段时间前做一些研究时发现的唯一一个。

于 2011-01-08T19:35:44.430 回答
2

github 上的tennera 项目包含一个基于 ANTLR 的 GNU Gettext PO/POT 解析器。我认为它被 Redhat 用于基于 Web 的翻译软件。

于 2011-11-24T18:03:21.533 回答
2

.MO 解析器(不是 Java,而是 Scala),解析为 Map:http ://scalamagic.blogspot.com/2013/03/simple-gettext-parser.html ,来源:http://pastebin.com/csWx5Sbb

于 2013-04-11T12:38:13.780 回答
0

我发现了一些 java 类来读写 po 文件:https ://launchpad.net/po-parser

于 2013-04-16T10:54:27.177 回答