这里有一个 Java 解决方案的想法(当然sed 也可以使用)。
String incorrectDuration = "PT10HMS";
String dur = incorrectDuration.replaceAll("(?<!\\d+)[HMS]", "0$0");
这会产生
PT10H0M0S
我个人更喜欢删除前面没有数字的字母:
String dur = incorrectDuration.replaceAll("(?<!\\d+)[HMS]", "");
现在我明白了
PT10H
Duration.parse(dur) 在这两种情况下都能正常工作并给出预期的结果。
(?<!\\d+) 是一个否定的lookbehind:只有当 H、M 或 S 前面没有数字字符串时,正则表达式才会匹配。
编辑:我可能在下面做得过火了。我只是好奇如何在您在评论中提到的 PTHMS 的情况下生成我喜欢的字符串。对于生产代码,您可能希望坚持使用上述更简单的解决方案。
String durationString = "PTHMS";
// if no digits, insert 0 before last letter
if (! durationString.matches(".*\\d.*")) {
durationString = durationString.replaceFirst("(?=[HMS]$)", "0");
}
// then delete letters that do not have a digit before them
durationString = durationString.replaceAll("(?<!\\d)[HMS]", "");
这会产生
PT0S
(?=[HMS]$) 是一个前瞻。它匹配空字符串,但前提是该空字符串后跟 H、M 或 S,然后是字符串的结尾。所以用0 替换这个空字符串给了我们PTHM0S。确信字符串中现在至少有一个数字,我们可以继续删除前面没有数字的字母。
如果您只有 PT,它仍然无法正常工作。据我了解,这不会发生。如果是这样,您会更喜欢在 if 语句中使用例如 durationString = PT0S;。