gpt4 book ai didi

regex - Perl中匹配日期的正则表达式

转载 作者:行者123 更新时间:2023-12-05 08:14:44 25 4
gpt4 key购买 nike

我想匹配具有以下格式的日期:

2010-08-27 02:11:36

yyyy-mm-dd hh:mm:ss

现在我对实际可行的日期不是很在意,只是它的格式正确。

应该匹配的可能格式是(对于这个例子)

2010
2010-08
2010-08-27
2010-08-27 02
2010-08-27 02:11
2010-08-27 02:11:36

在 Perl 中,什么可以是一个简洁的正则表达式?

到目前为止我已经有了这个(顺便说一句,这是可行的)

/\d{4}(-\d{2}(-\d{2}( \d{2}(:\d{2}(:\d{2})?)?)?)?)?/

这可以在性能方面得到改进吗?

最佳答案

基于一年中缺少捕获组,我假设您只关心日期是否匹配。

我尝试了几种与您的问题相关的不同模式,提高 10% 到 15% 的模式是禁用捕获,

/\d{4}(?:-\d{2}(?:-\d{2}(?: \d{2}(?::\d{2}(?::\d{2})?)?)?)?)?/

perlre documentation封面 (?:...) :

(?:pattern)

(?imsx-imsx:pattern)

This is for clustering, not capturing; it groups subexpressions like (), but doesn't make backreferences as () does. So

@fields = split(/\b(?:a|b|c)\b/)

is like

@fields = split(/\b(a|b|c)\b/)

but doesn't spit out extra fields. It's also cheaper not to capture characters if you don't need to.

Any letters between ? and : act as flags modifiers as with (?imsx-imsx). For example,

/(?s-i:more.*than).*million/i

is equivalent to the more verbose

/(?:(?s-i)more.*than).*million/i

基准输出:

             Rate      U   U/NC CH/NC/A CH/NC/A/U     CH  CH/NC   nullU         31811/s     --   -32%    -58%      -59%   -61%   -66%   -93%U/NC      46849/s    47%     --    -38%      -39%   -42%   -50%   -90%CH/NC/A   76119/s   139%    62%      --       -1%    -6%   -18%   -84%CH/NC/A/U 76663/s   141%    64%      1%        --    -6%   -17%   -84%CH        81147/s   155%    73%      7%        6%     --   -13%   -83%CH/NC     92789/s   192%    98%     22%       21%    14%     --   -81%null     481882/s  1415%   929%    533%      529%   494%   419%     --

Code:

#! /usr/bin/perl

use warnings;
use strict;

use Benchmark qw/ :all /;

sub option_chain {
local($_) = @_;
/\d{4}(-\d{2}(-\d{2}( \d{2}(:\d{2}(:\d{2})?)?)?)?)?/
}

sub option_chain_nocap {
local($_) = @_;
/\d{4}(?:-\d{2}(?:-\d{2}(?: \d{2}(?::\d{2}(?::\d{2})?)?)?)?)?/
}

sub option_chain_nocap_anchored {
local($_) = @_;
/\A\d{4}(?:-\d{2}(?:-\d{2}(?: \d{2}(?::\d{2}(?::\d{2})?)?)?)?)?\z/
}

sub option_chain_anchored_unrolled {
local($_) = @_;
/\A\d\d\d\d(-\d\d(-\d\d( \d\d(:\d\d(:\d\d)?)?)?)?)?\z/
}

sub simple_split {
local($_) = @_;
split /[ :-]/;
}

sub unrolled {
local($_) = @_;
grep defined($_), /\A (\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d) \z
|\A (\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d) \z
|\A (\d\d\d\d)-(\d\d)-(\d\d) (\d\d) \z
|\A (\d\d\d\d)-(\d\d)-(\d\d) \z
|\A (\d\d\d\d)-(\d\d) \z
|\A (\d\d\d\d) \z
/x;
}

sub unrolled_nocap {
local($_) = @_;
grep defined($_), /\A \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d \z
|\A \d\d\d\d-\d\d-\d\d \d\d:\d\d \z
|\A \d\d\d\d-\d\d-\d\d \d\d \z
|\A \d\d\d\d-\d\d-\d\d \z
|\A \d\d\d\d-\d\d \z
|\A \d\d\d\d \z
/x;
}

sub id { $_[0] }

my @examples = (
"xyz",
"2010",
"2010-08",
"2010-08-27",
"2010-08-27 02",
"2010-08-27 02:11",
"2010-08-27 02:11:36",
);

cmpthese -1 => {
"CH" => sub { option_chain $_ for @examples },
"CH/NC" => sub { option_chain_nocap $_ for @examples },
"CH/NC/A" => sub { option_chain_nocap_anchored $_ for @examples },
"CH/NC/A/U" => sub { option_chain_anchored_unrolled $_ for @examples },
"U" => sub { unrolled $_ for @examples },
"U/NC" => sub { unrolled_nocap $_ for @examples },
"null" => sub { id $_ for @examples },
};

关于regex - Perl中匹配日期的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3600124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com