我还在学习Perl正则表达式,我需要匹配一个表示时间的字符串。
但是有些情况下会输入多次。而不是' 9 AM'我有时候会在上午9点到下午9点。或者' 09 AM05PM' ...等等...幸运的是,它总是以一两个数字开头,以“AM'或者' PM' (大写和小写)
这是我到目前为止所拥有的:
$string =~ /^((([1-9])|(1[0-2]))*(A|P)M)$/i;
非常感谢任何帮助!
答案 0 :(得分:1)
我可以使用您自己的代码看到的唯一问题是,小时字段是可选的(因为您使用的是*
),但您不会说出您遇到的问题。
你确实有很多不必要的捕获。括在括号中的模式的每个部分都将在名为$1
,$2
等的内部变量中捕获目标字符串的相应部分。除非您确实需要这些捕获,否则最好使用非捕获括号(?: ... )
而不是普通的( ... )
。
像[1-9]
这样的字符类是单个实体,不需要括在括号中。您还没有在小于10的值上占据前导零,并且您应该使用字符类[AP]
而不是替换(?:A|P)
看起来你需要
/\d{1,2}[AP]M/i
但是,一旦找到它们,你就不会说出你想要做的时间。
这段代码通过将字符串中找到的所有时间放入数组@times
然后使用空格分隔符打印来演示功能。
use strict;
use warnings;
for my $string (qw/ 9AM 9AM5PM 09AM05PM /) {
my @times = $string =~ /\d{1,2}[AP]M/ig;
print "@times\n";
}
<强>输出强>
9AM
9AM 5PM
09AM 05PM
如果您确实想验证小时值是否在范围内(您是否可能遇到35pm
?)那么您可以写
my @times = $string =~ / (?: 1[012] | 0?[1-9] ) [AP]M /igx
请注意,/x
修饰符会使正则表达式中的空格无关紧要,因此可以用它来阐明模式的形式。
答案 1 :(得分:0)
您可以尝试以下内容:
$string =~ /^((0?\d|1[0-2])[AP]M)+$/i;
正如您所见here。或者:
$string =~ /^((0?\d|1[0-2])[AP]M){1,2}$/i;
如果你想一起长达2个小时。