2

在我从事的一个项目中,我们最近遇到了需要检查 2 个字符串是否具有字符串格式的问题(用于翻译)。

/* A simple example: */
str = "%.200sSOMETEXT%.5fSOMEMORETEXT%d%ul%.*s%%";

/* Should be able to be validated to be the equivalent of: */
str = "%.200sBLAHBLAH%.5ftest%d%ul%.*s%%MORETEXT";

/* and... */
str = "%.200s%.5f%d%ul%.*s%%";

/* but not... */
str = "%.5f%.200s%d%ul%%%.*s";

所以我的问题是:

有没有办法验证 2 个字符串是否具有等价字符串格式?

也许答案是一些非常好的正则表达式,或者现有的工具或来自另一个项目的一些示例代码。我无法想象我们是第一个遇到这个问题的项目。

4

2 回答 2

1

有趣的问题。

我会尝试实现一个从格式化字符串中去除非格式化字符的函数,从而只留下格式说明符。然后,希望它足够规范,可以进行比较。

也许您需要进一步去除字段宽度和(如果您支持的话)参数索引之类的东西,因为它们对于不同的翻译会有所不同。

想出剥离功能应该不难,格式说明符非常简单。删除字符直到找到 a %,然后检查以下字符,如果它%同时删除两个字符,否则复制字符直到找到“最终”说明符之一(dfsu)。

于 2013-10-17T08:03:30.587 回答
1

作为跟进/精确,我们的用例是验证翻译(po 文件),因为 org 字符串和已翻译的字符串之间的 printf 不匹配会导致严重的崩溃……</p>

目前我正在使用该正则表达式(python 代码,因为我们在 py 中处理它),这是 printf 语法的基本表示:

>>> import re
>>> _format = re.compile(r"(?!<%)(?:%%)*%[-+#0]?(?:\*|[0-9]+)?(?:\.(?:\*|[0-9]+))?(?:[hljztL]|hh|ll)?[tldiuoxXfFeEgGaAcspn]").findall
>>> _format("%.200sSOMETEXT%.5fSOMEMORETEXT%d%ul%.*s%%")
['%.200s', '%.5f', '%d', '%u', '%.*s']
>>> _format("%.200sBLAHBLAH%.5ftest%d%ul%.*s%%MORETEXT")
['%.200s', '%.5f', '%d', '%u', '%.*s']
>>> _format("%.200s%.5f%d%ul%.*s%%")
['%.200s', '%.5f', '%d', '%u', '%.*s']

所以返回列表之间的简单比较就可以告诉我们这些字符串是否与 printf 兼容。

这可能无法解决所有可能的极端情况,但效果很好……</p>

于 2013-10-17T08:33:15.270 回答