是否有用于解析gettext PO文件的Java库?

是否有用于解析gettext PO文件的Java库?,java,api,scala,gettext,po,Java,Api,Scala,Gettext,Po,有人知道Java库可以让我解析.PO文件吗?我只是想创建一个ID和值的映射,以便将它们加载到数据库中 是我在前一段时间做一些研究时发现的唯一一个。据我所知,您可以使用msgfmt--java2程序将PO文件转换为ResourceBundle类,并使用java.util.ResourceBundle或gnu.gettext.GettextResource读取它—我认为这是一种最有效的方法。执行与调用msgfmt完全相同的操作,包括创建中间流程,因为它的位置如下所示: Gettext Commons

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

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

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

Gettext Commons是一个Java库,使用GNUGettext实用程序的


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

我在互联网上搜索,也找不到现有的库。如果您使用Scala,由于它的解析器组合器特性,您自己编写解析器非常容易

调用
PoParser.parsePo(“po文件内容”)
。结果是一个
翻译列表

我已经将这段代码制作成一个库(可以被任何JVM语言使用,当然包括Java!):


包含GNU Gettext PO/POT的基于ANTLR的解析器。我认为Redhat将其用于基于web的翻译软件。

.MO解析器(不是Java,而是Scala),解析为Map:,来源:

我找到了一些Java类来读取和写入po文件:

你到底需要做什么?po文件是由GNU gettextI生成的资源文件,我希望避免将其转换为进程,例如,属性文件,但这是一个选项。另一种选择是编写解析器…@Mike Sickler如果我说的是显而易见的,请原谅我,但是如果你自己编写解析器,gettext包中的
DumpResource.java
可能会有用。我在该项目中找不到实际读取PO文件的代码。是吗?Gettext commons将msgfmt调用为中间步骤,因此无法避免创建进程。看到这个图欢迎来到Stackoverflow!一般来说,我们喜欢网站上的答案能够独立存在——链接很棒,但如果链接中断,答案应该有足够的信息仍然有用。请考虑编辑您的答案,包括更多的细节。有关更多信息,请参阅。第一个链接无法使用:“此博客仅对受邀读者开放”。很好,+1用于使用ScalaI也尝试了同样的功能,请告诉我如何在java项目中使用'msgfmt'将po转换为ResourceBundle。它看起来像命令。对于任何人来说,gettext库是作为JGettext从Tennera中分离出来的:
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
  }
}