Java 包含多种日期格式的正则表达式
选择什么正则表达式来覆盖以下所有场景: 基本上我必须提取前缀和后缀 前缀.YYYY-MM-DD-HH-MM-SS.后缀 YYYY-MM-DD是强制性的 HH-MM-SS是可选的。(它可以是HH-only或HH-MM或HH-MM-SS) 样本: “test1.2020-03-07-00.test.com” “test2.2020-03-06-16.test2.test1.com” “test3.2020-03-06-16-13-40.test2.test1.com” “test4.2020-03-06-16-13.test.com” “test5.ext.2020-03-11-17-57.test1.com” “test6.ext.2020-03-11.test1.test2.test3.com” 我使用此正则表达式,但它失败:Java 包含多种日期格式的正则表达式,java,regex,Java,Regex,选择什么正则表达式来覆盖以下所有场景: 基本上我必须提取前缀和后缀 前缀.YYYY-MM-DD-HH-MM-SS.后缀 YYYY-MM-DD是强制性的 HH-MM-SS是可选的。(它可以是HH-only或HH-MM或HH-MM-SS) 样本: “test1.2020-03-07-00.test.com” “test2.2020-03-06-16.test2.test1.com” “test3.2020-03-06-16-13-40.test2.test1.com” “test4.2020-03-
Pattern.compile(".\\d{4}-\\d{2}-\\d{2}(-\\d{2}-\\d{2}-\\d{2})?.*?");
这里有一个解决方案:
(.+)\.\d{4}(?:-\d{2}){2,5}\.(.+)
例如:
var pattern = Pattern.compile("(.+)\\.\\d{4}(?:-\\d{2}){2,5}\\.(.+)");
var matcher = pattern.matcher("test1.2020-03-07-00.test.com");
if(matcher.matches())
{
String prefix = matcher.group(1);
String suffix = matcher.group(2);
System.out.println("prefix: " + prefix);
System.out.println("suffix: " + suffix);
}
输出:
prefix: test1
suffix: test.com
首先请记住,
句点是一个特殊的正则表达式模式,它匹配任何字符,因此要特别匹配句点,需要将其转义为\。
您自己说过时间部分“可以是HH only或HH-MM或HH-MM-SS”,因此您不应该期望(\\d{2}-\\d{2}-\\d{2})
与之匹配。由于您不需要捕获它,请使用(?:…)
非捕获组,并将它们嵌套为:(?:-\\d{2}(?:-\\d{2}(?:-\\d{2})?
。更好的是,因为这三个部分是相同的,所以使用(?:-\\d{2}){0,3}
你说“我必须提取前缀和后缀”,所以你应该将其添加到模式中
Pattern p = Pattern.compile("^(.*?)\\.(\\d{4}(?:-\\d{2}){2,5})\\.(.*)$");
for (String s : new String[] { "test1.2020-03-07-00.test.com",
"test2.2020-03-06-16.test2.test1.com",
"test3.2020-03-06-16-13-40.test2.test1.com",
"test4.2020-03-06-16-13.test.com",
"test5.ext.2020-03-11-17-57.test1.com",
"test6.ext.2020-03-11.test1.test2.test3.com" }) {
Matcher m = p.matcher(s);
if (m.matches()) {
System.out.printf("prefix = '%s', date = '%s', suffix = '%s'%n",
m.group(1), m.group(2), m.group(3));
} else {
System.out.printf("NO MATCH: '%s'%n", s);
}
}
输出
前缀='test1',日期='2020-03-07-00',后缀='test.com'
前缀='test2',日期='2020-03-06-16',后缀='test2.test1.com'
前缀='test3',日期='2020-03-06-16-13-40',后缀='test2.test1.com'
前缀='test4',日期='2020-03-06-16-13',后缀='test.com'
前缀='test5.ext',日期='2020-03-11-17-57',后缀='test1.com'
前缀='test6.ext',日期='2020-03-11',后缀='test1.test2.test3.com'
我建议采用不同的方法。找到一个合适的正则表达式即使不是不可能,也是非常困难的。我处理了一个问题,从任何事先未知的可能格式解析日期,我想出了一个主意。当然,这个问题没有100%的解决方案,但我在这里做了什么。我创建了一个属性文件,其中包含当前支持的格式列表。当需要解析字符串时,将使用每个掩码连续进行尝试,直到成功解析日期或掩码用完为止。这个想法的优点
1.由于该文件是一个外部文件,因此可以使用其他格式不断更新,而无需更改代码。
2.文件可以在每个客户的基础上进行定制,您可以首先放置更可取的格式。例如,对于美国客户,您会将美国格式放在首位(例如MM dd YYYY和之后的欧洲格式。对于欧洲客户,反之亦然。因此,当日期如07-08-2000到来时,对于美国客户,将解析为7月8日,但对于欧洲客户,将解析为8月7日。因此,简言之,灵活性。
要了解更多详细信息,请阅读我的文章-您是否尝试过任何东西,或者您只是想让我们为您编写代码,因为您不必费心学习正则表达式?如果您确实尝试了一些东西,请展示您尝试过的东西,并解释您陷入困境的原因。
groupCount()
取决于模式,而不是输入,因此由于模式是硬编码文本,groupCount()==2
不能为false,并且是完全冗余的。
Pattern p = Pattern.compile("^(.*?)\\.(\\d{4}(?:-\\d{2}){2,5})\\.(.*)$");
for (String s : new String[] { "test1.2020-03-07-00.test.com",
"test2.2020-03-06-16.test2.test1.com",
"test3.2020-03-06-16-13-40.test2.test1.com",
"test4.2020-03-06-16-13.test.com",
"test5.ext.2020-03-11-17-57.test1.com",
"test6.ext.2020-03-11.test1.test2.test3.com" }) {
Matcher m = p.matcher(s);
if (m.matches()) {
System.out.printf("prefix = '%s', date = '%s', suffix = '%s'%n",
m.group(1), m.group(2), m.group(3));
} else {
System.out.printf("NO MATCH: '%s'%n", s);
}
}