2016-10-22 68 views
0

我试图在Java中使用正则表达式在字符串中查找时间。这里的正则表达式:在Java中使用正则表达式查找12小时格式的时间

\d{1,2}?:\d\d(?)(am|pm)?? 

应该寻找1位或2位,后跟一个冒号,两个数字,然后要么“是”或“PM”(大小写无关)。

它主要工作,但如果我在捕获组中包装整个正则表达式,我只会得到hh:mm。例如,“12:34 am”只返回“12:34”。没有“是”。

UPDATE:完整的代码示例

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()); 

任何人有任何想法,为什么?

+1

您正在寻找在错误的组。尝试组0.下次,请发布[mcve],而不仅仅是您认为相关的位。猜你在做什么不是最佳 – Tibrogargan

+1

为什么有这么多的问号?我是否错过了某些东西,或者这应该是'\ d {1,2}?:\ d \ d(am | pm)',或者am/pm是可选的\ d {1,2}:\ d \ d(am | pm)?' – 3ocene

+0

@ 3ocene我不认为这是一个有效的正则表达式,因为它是无论如何。什么是“(?)”? – Tibrogargan

回答

2

而非目前的模式,你可能需要使用\b(?:[01]?\d|2[0-3]):[0-5]?\d(?:[ap]m)?\b匹配次,不区分大小写的标志设置,甚至使用24小时符号和12h符号之间的替代品,以不同与am/pm

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

我真的不知道你的模式中的(?)

+0

我认为这可能实际上是这样做的,或多或少我尝试了正则表达式并且未能找到匹配,但是如果我使用'(?:[01]?\\ d | 2 [0-3]):[0-5]?\\ d *(?: am | AM | pm | PM)?' 。我不是AM/PM处理最后的忠实粉丝,但我确实已经捕获了这个问题,这是我的首要关注点,所以我可以在时间允许的情况下优化它。 – jasondlee

+0

是的,你不得不使用双反斜杠来实际使用,但是当你在你的问题中用标准符号来写你的正则表达式模式时,我认为它会很好用。 –

-1

对不起我编辑:\d?\d:\d?\d["a"|"p"|"A"|"P"]["m"|"M"]

+0

这似乎并不真正回答原来的问题。是的,它可能会匹配一次,但它也会匹配很多其他的东西,比如'1234567890:0987654321 |'' – 3ocene

1

这与修改测试字符串匹配的情况下,删除多余的问号,并添加周围组得到正确的组。

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()); 
1

当你正在对12种小时格式匹配所以有很多束缚覆盖所以从不使用\d,因为它会接受用户发出的任何数量的号码输入你的正则表达式将无法针对这些无效的情况下,像13:32am22:23am或许多其他非-12小时格式

所以,使其健壮使用

\\b(1[012]|0[1-9]):([0-5][0-9])(\\s)?([Aa]|[pP])[mM]

\\b(1[012]|0?[1-9]):\\b字边界然后要么10,11,12或从00-59

(\\s)?01-9

:([0-5][0-9]):字符匹配的数字可以有一个单一的空间

([Aa]|[pP])[mM]要么是,上午或下午,PM等

完整的代码将是

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:21am1:1am使用灵活

\\b(1[012]|0?[1-9]):([0-5]?[0-9])(\\s)?([Aa]|[pP])[mM]