在我工作的项目中,我们最近遇到了一个问题,我们需要检查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个字符串是否具有等价字符串格式?
也许答案是一些非常好的正则表达式,或现有工具或来自另一个项目的一些示例代码。我无法想象我们是第一个遇到这个问题的项目。
答案 0 :(得分:1)
有趣的问题。
我会尝试实现一个从格式化字符串中去除非格式化字符的函数,因此只留下格式说明符。那么,希望这应该是规范的足以进行比较。
也许你需要进一步去掉像字段宽度这样的东西,并且(如果你支持的话)参数索引,因为不同的翻译会有所不同。
提出剥离功能应该不是很难,格式说明符非常简单。删除字符,直到找到%
,然后检查以下字符,如果是%
然后删除它们,则复制字符,直到找到其中一个“最终”说明符(d
,f
,s
,u
等等。
答案 1 :(得分:1)
正如后续/精确,我们的用例是验证翻译(po文件),因为组织字符串和翻译字符串之间的printf不匹配会导致令人讨厌的崩溃......
目前我正在使用那个正则表达式(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兼容。
这可能并不能解决所有可能的极端情况,但它的效果非常好......