Нужна помощь в регулярных выражениях в perl - PullRequest
0 голосов
/ 01 марта 2020

Мне нужно получить определенное значение из каждой строки, показанной ниже:

ABC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnx86
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnx86
GHI_ROOT|/home/test/test_3/GHI/GHI19.10.199/lnx86/tools.lnx86
JKL_ROOT|/home/test/test_4/JKL/JKL19.00.000/lnx86
ABC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnppc
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnppc

Из приведенных выше строк я хочу получить значения, имеющие номера версий ABC04.16.103, DEF19.20.100, GHI19.10.199, JKL19.00.000 только для lnx86.

Я попробовал приведенное ниже регулярное выражение, но оно дает результат для lnx86 и lnpp c:

 /([A-Z]{3}\d{2}\.\d{2}\.\d{3})/

Ответы [ 3 ]

4 голосов
/ 01 марта 2020

Хороший шаблон включает в себя все, что вам нужно, чтобы соответствовать интересующим данным, но также достаточно информации, чтобы исключить неинтересные данные. Поскольку вам нужны только строки с lnx86, сделайте эту часть вашего шаблона. Я написал это с помощью /x, чтобы разложить шаблон, чтобы облегчить грок:

while( <DATA> ) {
    next unless m|
        /
        ( [A-Z]{3} \d{2} \.\d{2} \.\d{3} )   # $1
        /
        lnx86
        (?: / | \Z ) # another slash or end of string
        |x;

    print;
    }

__END__
BC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnx86
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnx86
GHI_ROOT|/home/test/test_3/GHI/GHI19.10.199/lnx86/tools.lnx86
JKL_ROOT|/home/test/test_4/JKL/JKL19.00.000/lnx86
ABC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnppc
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnppc

Это выбирает строки, которые вы хотите:

BC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnx86
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnx86
GHI_ROOT|/home/test/test_3/GHI/GHI19.10.199/lnx86/tools.lnx86
JKL_ROOT|/home/test/test_4/JKL/JKL19.00.000/lnx86

Вы можете немного обобщите, чтобы позже вы могли выбрать другой инструмент. Используйте quotemeta, чтобы убедиться, что ничто в значении не является метасимволом регулярного выражения (если это не то, что вы хотите):

my $tool = quotemeta( 'lnx86' );

while( <DATA> ) {
    next unless m|
        /
        ( [A-Z]{3} \d{2} \.\d{2} \.\d{3} )   # $1
        /
        $tool
        (?: / | \Z ) # another slash or end of string
        |x;

    print;
    }
1 голос
/ 01 марта 2020

Просто добавьте позитивный прогноз в конце, чтобы он совпадал только с lnx86 следующим образом: /([A-Z]{3}\d{2}\.\d{2}\.\d{3})(?=/lnx86)/. Таким образом, он будет соответствовать вашему шаблону, только если за ним следует строка /lnx86.

0 голосов
/ 01 марта 2020

Это то, что вы после?

use strict;
use warnings;
use feature 'say';

for (<DATA>) {                     # walk through data
    say $1 if m!([^/]+)/lnx86!;    # match pattern and output
}

__DATA__
ABC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnx86
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnx86
GHI_ROOT|/home/test/test_3/GHI/GHI19.10.199/lnx86/tools.lnx86
JKL_ROOT|/home/test/test_4/JKL/JKL19.00.000/lnx86
ABC_ROOT|/home/test/test_1/ABC/ABC-012/ABC04.16.103/lnppc
DEF_ROOT|/home/test/test_2/DEF/DEF192/DEF19.20.100/lnppc

Вывод

ABC04.16.103
DEF19.20.100
GHI19.10.199
JKL19.00.000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...