用Java中的正则表达式在字符串中查找12小时格式时间

用Java中的正则表达式在字符串中查找12小时格式时间,java,regex,Java,Regex,我试图在Java中使用正则表达式在字符串中查找时间。这是正则表达式: \d{1,2}?:\d\d(?)(am|pm)?? 这应该查找1或2个数字,后跟一个冒号,两个以上的数字,然后是“am”或“pm”(不考虑大小写) 它基本上是有效的,但是如果我将整个正则表达式包装在一个捕获组中,我只得到hh:mm。例如,“12:34am”只返回“12:34”。没有“am” 更新:完整代码示例 Pattern p = Pattern.compile("\\d{1,2}?:\\d\\d(?)(am|pm)??"

我试图在Java中使用正则表达式在字符串中查找时间。这是正则表达式:

\d{1,2}?:\d\d(?)(am|pm)??
这应该查找1或2个数字,后跟一个冒号,两个以上的数字,然后是“am”或“pm”(不考虑大小写)

它基本上是有效的,但是如果我将整个正则表达式包装在一个捕获组中,我只得到hh:mm。例如,“12:34am”只返回“12:34”。没有“am”

更新:完整代码示例

Pattern p = Pattern.compile("\\d{1,2}?:\\d\\d(?)(am|pm)??");
Matcher matcher = p.matcher("12:34AM");
Assert.assertTrue(matcher.find());
Assert.assertEquals("12:34AM", matcher.group());

有人知道为什么吗?

对不起,我编辑了:
\d?\d:\d?\d[“a”|“p”|“a”|“p”][“m”|“m”]
对不起,我编辑了:
\d?\d[“a”|“p”|“a”|“p”][“m”|“m”

这会让你的组正确地匹配测试字符串,删除周围多余的问号,并添加标记

Pattern p = Pattern.compile("(\\d{1,2}:\\d\\d(AM|PM)?)");
Matcher matcher = p.matcher("12:34AM");
Assert.assertTrue(matcher.find());
Assert.assertEquals("12:34AM", matcher.group());

通过修改测试字符串以匹配大小写、删除多余的问号并添加周围的组,可以正确地获取组

Pattern p = Pattern.compile("(\\d{1,2}:\\d\\d(AM|PM)?)");
Matcher matcher = p.matcher("12:34AM");
Assert.assertTrue(matcher.find());
Assert.assertEquals("12:34AM", matcher.group());

您可能希望使用
\b(?[01]?\d|2[0-3]):[0-5]?\d(?[ap]m)?\b
来匹配时间,设置不区分大小写的标志,甚至使用替代方法来区分24小时表示法和12小时表示法,并使用
am
/
pm

当前模式使用惰性可选模式来匹配
am
/
pm
(am | pm)?
),因为它位于模式的末尾,它将永远不会匹配(除非在.matches()而不是.find()的上下文中使用,因为它强制进行完全匹配)


老实说,我不确定您的模式中的
(?)

您可能希望使用
\b(?[01]?\d | 2[0-3]):[0-5]?\d(?[ap]m)?\b
来匹配时间,设置了不区分大小写的标志,甚至使用替代方法来区分24小时表示法和12小时表示法,并使用
am
/
pm

当前模式使用惰性可选模式来匹配
am
/
pm
(am | pm)?
),因为它位于模式的末尾,它将永远不会匹配(除非在.matches()而不是.find()的上下文中使用,因为它强制进行完全匹配)


老实说,我对
(?)
在您的模式中。

当您与12小时格式匹配时,会有很多内容需要覆盖,所以不要使用
\d
,因为它将接受用户提供的任何数字输入,并且您的正则表达式将无法抵抗这些无效情况,如
13:32am
22:23am
或许多其他非12小时格式

因此,要使其健壮,请使用

\\b(1[012]| 0?[1-9]):
\\b
单词边界然后
10,11,12
0
1-9

:([0-5][0-9])
字符匹配来自
00-59的数字

(\\s)?
可以有一个空格

([Aa]|[pP])[mM]
上午、上午或下午、下午等

完整的代码将是

    Pattern pattern=Pattern.compile("\\b(1[012]|0[1-9]):([0-5][0-9])(\\s)?([Aa]|[pP])[mM]");
    Matcher matcher=pattern.matcher("12:23am 12:6am  ds  13:32am dwdw c 01:12am ded 1:21am");

    while (matcher.find()) {
        System.out.println(matcher.group());
    } 
要使输入更灵活,如
1:21am
1:1am
使用


由于您要与12小时格式匹配,因此有许多内容必须涵盖,因此切勿使用
\d
,因为它将接受用户提供的任何数字输入,并且您的正则表达式将在这些无效情况下失败,如
13:32am
22:23am
或许多其他非12小时格式

因此,要使其健壮,请使用

\\b(1[012]| 0?[1-9]):
\\b
单词边界然后
10,11,12
0
1-9

:([0-5][0-9])
字符匹配来自
00-59的数字

(\\s)?
可以有一个空格

([Aa]|[pP])[mM]
上午、上午或下午、下午等

完整的代码将是

    Pattern pattern=Pattern.compile("\\b(1[012]|0[1-9]):([0-5][0-9])(\\s)?([Aa]|[pP])[mM]");
    Matcher matcher=pattern.matcher("12:23am 12:6am  ds  13:32am dwdw c 01:12am ded 1:21am");

    while (matcher.find()) {
        System.out.println(matcher.group());
    } 
要使输入更灵活,如
1:21am
1:1am
使用


您看到的是错误的组。请尝试组0。下次,请发表一篇文章,而不仅仅是你认为相关的内容。猜猜你在做什么不是最好的,为什么有这么多问号?我是否遗漏了什么,或者应该是
\d{1,2}?:\d\d(Am{124; pm)
或者如果Am/pm是可选的,
\d{1,2}:\d\d(Am{124; pm)
@3ocene我不相信它是一个有效的正则表达式。什么是
(?)
?我不熟悉Java正则表达式引擎,所以我想它可能会使下一个组无法捕获,但在谷歌搜索之后,它似乎与任何其他引擎一样:
\d{1,2}:\d\d(?:am | pm)
@Tibrogargan,我已经用一个完整的示例更新了代码,以回答我最初的问题。现在,我将尝试合并上面提到的各种更改,看看是否能够弄清这一点。:)你看错了群体。请尝试组0。下次,请发表一篇文章,而不仅仅是你认为相关的内容。猜猜你在做什么不是最好的,为什么有这么多问号?我是否遗漏了什么,或者应该是
\d{1,2}?:\d\d(Am{124; pm)
或者如果Am/pm是可选的,
\d{1,2}:\d\d(Am{124; pm)
@3ocene我不相信它是一个有效的正则表达式。什么是
(?)
?我不熟悉Java正则表达式引擎,所以我想它可能会使下一个组无法捕获,但在谷歌搜索之后,它似乎与任何其他引擎一样:
\d{1,2}:\d\d(?:am | pm)
@Tibrogargan,我已经用一个完整的示例更新了代码,以回答我最初的问题。现在,我将尝试合并上面提到的各种更改,看看是否能够弄清这一点。:)这似乎并没有真正回答最初的问题。是的,它可能会匹配一个时间,但它也会匹配许多其他东西,如
1234567890:0987654321 |“
这似乎并没有真正回答最初的问题。是的,它可能匹配一个时间,但它也会匹配许多其他东西,如
1234567890:0987654321 |”
我认为这实际上或多或少可以做到这一点。我原封不动地尝试了正则表达式,但失败了