Что такое регулярное выражение для извлечения маски даты в Perl? - PullRequest
3 голосов
/ 09 декабря 2011

У меня есть строка в perl, которая содержит спецификацию каталога.Если строка содержит какую-либо отдельную или комбинацию подстрок, которые составляют маску даты, я хочу извлечь эту подстроку.Например, спецификация каталога может быть:

/mydir/data/YYYYMMDD

Я хочу иметь возможность извлечь строку "YYYYMMDD".Однако эта часть пути может быть любой индивидуальной или комбинацией следующих строк:

YY
YYYY
MM
DD

Таким образом, строка спецификации каталога может иметь вид:

   /mydir/data/DD/data2

, и я хочу "DD"возвращается в результате сравнения регулярных выражений.Как перехватить строку, если она должна содержать одну или несколько из этих строк маски даты, и эта строка должна быть между двумя символами "/" или существовать в конце строки?

Ответы [ 4 ]

4 голосов
/ 09 декабря 2011

Я предполагаю, что YYYY и YY не должны появляться в одном шаблоне, поскольку в противном случае это не имеет смысла.

use Data::Munge qw(list2re);
use List::MoreUtils qw(uniq);
use Algorithm::Combinatorics qw(variations);
use Perl6::Take qw(gather take);

list2re
uniq
gather {
    for my $n ([qw(YYYY MM DD)], [qw(YY MM DD)]) {
        for my $k (1..scalar @$n) {
            take map { join q(), @$_ } variations($n, $k)
        }
    }
}

Выражение возвращает регулярное выражение (?^:DDMMYYYY|DDYYYYMM|MMDDYYYY|MMYYYYDD|YYYYDDMM|YYYYMMDD|DDMMYY|DDYYMM|DDYYYY|MMDDYY|MMYYDD|MMYYYY|YYDDMM|YYMMDD|YYYYDD|YYYYMM|DDMM|DDYY|MMDD|MMYY|YYDD|YYMM|YYYY|DD|MM|YY). (Полу-) Функциональное программирование на победу!

1 голос
/ 09 декабря 2011

Я предполагаю, что есть только один компонент "date", а если нет, то вам нужен первый:

#!/usr/bin/perl
use warnings;
use strict;

my @paths = qw(
    /mydir/data/YYYYMMDD
    /mydir/data/YY/data2
    /mydir/data/YYMM/data2
    /mydir/data/DD/data2
);

foreach my $path (@paths) {
    my($date) = grep /^(([YMD])\2)+$/, split '/', $path;
    print "$path: $date\n";
}
1 голос
/ 09 декабря 2011

Предполагая, что поля маски всегда в порядке Y - M - D, это будет делать то, что вам нужно:

my ($mask) = $path =~ m{ / ( (?:YY){0,2} (?:MM)? (?:DD)? ) (?:/|$) }x;
0 голосов
/ 09 декабря 2011

Я бы использовал

my ($date) = m{/([0-9]{2,8})(?:/|$)}

и проверил бы

not(length($date) % 2)   # $date has even length

и, возможно, несколько проверок на допустимые комбинации.

Обновление: ОК, чтобы получить маску, а не цифры, вы можете изменить это значение на

my ($date) = m{/([YMD]{2,8})(?:/|$)};
my $check = $date;
$check =~ s/YYYY/y/;
$check =~ s/MM//;
$check =~ s/DD//;
print "Matches $date\n" if grep $_ eq $check, (q{}, 'y', 'YY');

Это должно исключить все недопустимые комбинации, такие какГГДГГГ или ГГГГММГГ и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...