简体   繁体   English

使用Java中的Regex在字符串中查找12小时格式的时间

[英]Finding 12-hour format Time in a String with Regex in Java

I'm trying to find a time in a String using a regex in Java. 我正在尝试使用Java中的正则表达式在字符串中查找时间。 Here's the regex: 这是正则表达式:

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

That should look for 1 or 2 digits, followed by a colon, two more digits, then either "am" or "pm" (irrespective of case). 应该寻找1或2位数字,然后是冒号,再输入两位数,然后是“ am”或“ pm”(与大小写无关)。

It mostly works, but if I wrap that entire regex in a capture group, I only get hh:mm. 它通常可以工作,但是如果我将整个正则表达式包装在捕获组中,则只会得到hh:mm。 For example, "12:34am" returns just "12:34". 例如,“ 12:34 am”仅返回“ 12:34”。 No "am". 没有“上午”。

UPDATE: Full code example 更新:完整代码示例

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

Anyone have any idea why? 有人知道为什么吗?

Instead of your current pattern, you might want to use \\b(?:[01]?\\d|2[0-3]):[0-5]?\\d(?:[ap]m)?\\b to match times, with the case-insensitive flag set or even use alternatives to distinct between 24h notation and 12h notation with am / pm 您可能要使用\\b(?:[01]?\\d|2[0-3]):[0-5]?\\d(?:[ap]m)?\\b ,而不是当前的模式匹配时间,设置不区分大小写的标志,甚至使用替代方法来区分am / pm 24小时表示法和12小时表示法

Your current pattern uses a lazy optional pattern to match the am / pm ( (am|pm)?? ), as this is at the end of the pattern, it will never match (except when used in the context of .matches() instead of .find(), as it forces a full match). 您当前的模式使用一个懒惰的可选模式来匹配am / pm(am|pm)?? ),因为它位于模式的末尾,它将永远不会匹配(除非在.matches()上下文中使用)而不是.find(),因为它会强制进行完全匹配)。

I'm honestly not sure about the (?) in your pattern. 老实说,我不确定您的模式中的(?)

This gets your group correctly with modifications to the test string to match case, remove extraneous question marks and to add the surrounding 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());

As you are matching against 12 hour format so there are many bound to cover so never use \\d because it will accept any number number input given by user and your regex will fail against these invalid cases like 13:32am 22:23am or many others non-12 hour formats 由于您要匹配12小时格式,因此有很多内容需要覆盖,因此请不要使用\\d因为它将接受用户提供的任何数字输入,并且您的正则表达式将无法处理这些无效情况,例如13:32am 22:23am或其他许多情况非12小时格式

so to make it robust use 使其坚固耐用

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

\\\\b(1[012]|0?[1-9]): \\\\b word boundary then either 10,11,12 or 0 with 1-9 \\\\b(1[012]|0?[1-9]): \\\\b字边界,然后是10,11,1201-9

:([0-5][0-9]) : character match digits from 00-59 :([0-5][0-9]) :字符匹配的数字,从00-59

(\\\\s)? there can be a single space 可以有一个空格

([Aa]|[pP])[mM] either am,AM or pm,PM etc ([Aa]|[pP])[mM]上午,上午或下午,下午等

Complete code would be 完整的代码将是

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

To make it more flexible for inputs like 1:21am and 1:1am use 为了更灵活地使用诸如1:21am1:1am这样的输入

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

抱歉,我编辑了以下内容: \\d?\\d:\\d?\\d["a"|"p"|"A"|"P"]["m"|"M"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM