Как получить значения в непостоянной позиции? - PullRequest
0 голосов
/ 20 июня 2019

Строка содержит:

#EXT-X-STREAM-INF:BANDWIDTH=1439890,RESOLUTION=640x480,CODECS="avc1.42001f,mp4a.40.2"

Порядок пар ключ-значение не является постоянным.Примеры:

#EXT-X-STREAM-INF:BANDWIDTH=1439890,RESOLUTION=640x480,CODECS="avc1.42001f,mp4a.40.2"
#EXT-X-STREAM-INF:RESOLUTION=640x480,BANDWIDTH=1439890,CODECS="avc1.42001f,mp4a.40.2"
#EXT-X-STREAM-INF:CODECS="avc1.42001f,mp4a.40.2",RESOLUTION=640x480,BANDWIDTH=1439890

Как получить значения в непостоянной позиции пар, используя одно регулярное выражение?Этот пример для постоянной позиции пар:

my $str = '#EXT-X-STREAM-INF:BANDWIDTH=1439890,RESOLUTION=640x480,CODECS="avc1.42001f,mp4a.40.2"';
if ($str =~/#EXT-X-STREAM-INF:BANDWIDTH=(?'bandwidth'.+?),RESOLUTION=(?'resolution'.+?),CODECS="(?'codecs'.+?)"$/) {
    say $+{bandwidth};
    say $+{resolution};
    say $+{codecs};
}

Ответы [ 2 ]

3 голосов
/ 20 июня 2019

Используйте положительный прогноз:

while(<DATA>) {
    print;
    if (/^#EXT-X-STREAM-INF:(?=.*BANDWIDTH=(?'bandwidth'[^,]+))(?=.*RESOLUTION=(?'resolution'[^,]+))(?=.*CODECS="(?'codecs'[^"]+))/) {
        say $+{bandwidth};
        say $+{resolution};
        say $+{codecs};
    } else {
        say 'NO match';
    }
}

__DATA__
#EXT-X-STREAM-INF:BANDWIDTH=1439890,RESOLUTION=640x480,CODECS="avc1.42001f,mp4a.40.2"
#EXT-X-STREAM-INF:RESOLUTION=640x480,BANDWIDTH=1439890,CODECS="avc1.42001f,mp4a.40.2"
#EXT-X-STREAM-INF:CODECS="avc1.42001f,mp4a.40.2",RESOLUTION=640x480,BANDWIDTH=1439890

Вывод:

#EXT-X-STREAM-INF:BANDWIDTH=1439890,RESOLUTION=640x480,CODECS="avc1.42001f,mp4a.40.2"
1439890
640x480
avc1.42001f,mp4a.40.2
#EXT-X-STREAM-INF:RESOLUTION=640x480,BANDWIDTH=1439890,CODECS="avc1.42001f,mp4a.40.2"
1439890
640x480
avc1.42001f,mp4a.40.2
#EXT-X-STREAM-INF:CODECS="avc1.42001f,mp4a.40.2",RESOLUTION=640x480,BANDWIDTH=14398901439890
640x480
avc1.42001f,mp4a.40.2
2 голосов
/ 20 июня 2019

Самый простой способ - это сначала извлечь все значения в хеш:

use v5.12.0;
use warnings;

my @variants = (
    '#EXT-X-STREAM-INF:BANDWIDTH=1439890,RESOLUTION=640x480,CODECS="avc1.42001f,mp4a.40.2"',
    '#EXT-X-STREAM-INF:RESOLUTION=640x480,BANDWIDTH=1439890,CODECS="avc1.42001f,mp4a.40.2"',
    '#EXT-X-STREAM-INF:CODECS="avc1.42001f,mp4a.40.2",RESOLUTION=640x480,BANDWIDTH=1439890',
);

for my $str (@variants) {
    say "trying $str ...";
    my %data = $str =~ /(\w+)=(?|([^",]+)|"([^"]*)")/g;

    say "bandwidth:  $data{BANDWIDTH}";
    say "resolution: $data{RESOLUTION}";
    say "codecs:     $data{CODECS}";
    say "";
}

Живая демоверсия .

m//g в контексте списка пытается найти совпадениестолько раз, сколько возможно и возвращает список всех захваченных строк.В этом случае каждое совпадение вносит два перехвата (из-за шаблона сброса ветви (?|...) последние две альтернативы считаются одной группой).

Присвоение списка хешу интерпретирует элементы в четных позициях как ключи инечетные элементы в качестве соответствующих значений.

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