首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RegEx用于验证正确的ISO8601日期字符串

RegEx用于验证正确的ISO8601日期字符串
EN

Stack Overflow用户
提问于 2019-05-10 14:44:14
回答 3查看 6.2K关注 0票数 2

例如:2013-08-11T17:22:04.51+01:00

在这个stackoverflow回答中,涵盖了没有.51部件的ISODateTime。

请帮助更正此正则表达式。

代码语言:javascript
复制
^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$

来处理我的格式。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-10 14:54:45

使用捕获组,您可以简单地设计一个表达式,以便从输入中捕获任何您想要的内容。例如这句话

代码语言:javascript
复制
(\d{4}-\d{2}-\d{2})[A-Z]+(\d{2}:\d{2}:\d{2}).([0-9+-:]+)

将您的输入分成三个捕获组,您可以使用$1-3调用它们。

您还可以在[]中添加任何想要添加的字符。

RegEx描述图

此图显示了表达式的工作方式,您可以在此链接中可视化其他表达式。

Java测试

代码语言:javascript
复制
import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "(\\d{4}-\\d{2}-\\d{2})[A-Z]+(\\d{2}:\\d{2}:\\d{2}).([0-9+-:]+)";
final String string = "2013-08-11T17:22:04.51+01:00";
final String subst = "\\1 \\2 \\3";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);

System.out.println("Substitution result: " + result);

JavaScript演示

代码语言:javascript
复制
const regex = /(\d{4}-\d{2}-\d{2})[A-Z]+(\d{2}:\d{2}:\d{2}).([0-9+-:]+)/gm;
const str = `2013-08-11T17:22:04.51+01:00`;
const subst = `\nGroup 1: $1\nGroup 2: $2\nGroup 3: $3\n`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

基本性能测试

这个JavaScript片段使用一个简单的100万次for循环来显示表达式的性能。

代码语言:javascript
复制
const repeat = 1000000;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
	const string = '2013-08-11T17:22:04.51+01:00';
	const regex = /(\d{4}-\d{2}-\d{2})[A-Z]+(\d{2}:\d{2}:\d{2}).([0-9+-:]+)/gm;
	var match = string.replace(regex, "\nGroup #1: $1 \n Group #2: $2 \n Group #3: $3 \n");
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match  ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test.  ");

票数 4
EN

Stack Overflow用户

发布于 2019-06-06 11:45:37

正则表达式有时很方便,但通常很难阅读,(正如您所经历的)很难调试。Java内置了对ISO8601格式的解析和验证,它接受带有和不带小数的字符串,比如.51。我理解您的要求,因为您需要通过javax.validation进行验证,这需要正则表达式。因此,只对其他读者:选择是显而易见的:这里不要使用regex。

代码语言:javascript
复制
    try {
        OffsetDateTime.parse("2013-08-11T17:22:04.51+01:00");
        System.out.println("Valid ISO 8601");
    } catch (DateTimeParseException e) {
        System.out.println("Not valid ISO 8601");
    }

有效ISO 8601

警告:OffsetDateTime.parse仍然不接受ISO8601的所有变体,但是比正则表达式接受的变体要多得多。

票数 4
EN

Stack Overflow用户

发布于 2019-05-10 14:46:55

这个regex应该做好以下工作:

代码语言:javascript
复制
^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$

参考https://www.myintervals.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56079929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档