我们得到的xml具有无效的持续时间,如PT10HMS(注意在M和S之前缺少数字)。我通过读取文件并通过逐个字符迭代持续字符串并在两个并排的字母之间插入0来解决这个问题(P和T之间除外)。我想知道是否有更优雅的解决方案可能使用带有sed或其他任何东西的正则表达式?
感谢任何建议
答案 0 :(得分:1)
这里有一个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+)
是负面的后视:如果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
,它仍然无效。据我了解,这不会发生。如果是这样,您更愿意在durationString = PT0S;
语句中使用if
代替。