Как я могу извлечь подстроки из строки в Perl?
Рассмотрим следующие строки:
1) Идентификатор схемы: abc-456-hu5t10 (Высокий приоритет) *****
2) Идентификатор схемы: frt-78f-hj542w (Сбалансированный)
3) Идентификатор схемы: 23f-f974-nm54w (пробег супер-формулы) *****
и т.д. в вышеуказанном формате - выделенные жирным шрифтом изменения в строках.
== > Представьте, что у меня много строк формата. Я хочу выбрать 3 подстроки (как показано в BOLD ниже) из каждой из приведенных выше строк.
- 1-я подстрока, содержащая буквенно-цифровое значение (например, над ним "abc-456-hu5t10" )
- Вторая подстрока, содержащая слово (например, над ним "Высокий приоритет" )
- Третья подстрока, содержащая * (
IF
*, присутствует в конце строки ELSE
оставьте ее)
Как выбрать эти 3 подстроки из каждой строки, показанной выше? Я знаю, что это можно сделать с помощью регулярных выражений в Perl... Можете ли вы помочь с этим?
Ответы
Ответ 1
Вы можете сделать что-то вроде этого:
my $data = <<END;
1) Scheme ID: abc-456-hu5t10 (High priority) *
2) Scheme ID: frt-78f-hj542w (Balanced)
3) Scheme ID: 23f-f974-nm54w (super formula run) *
END
foreach (split(/\n/,$data)) {
$_ =~ /Scheme ID: ([a-z0-9-]+)\s+\(([^)]+)\)\s*(\*)?/ || next;
my ($id,$word,$star) = ($1,$2,$3);
print "$id $word $star\n";
}
Ключевое значение имеет регулярное выражение:
Scheme ID: ([a-z0-9-]+)\s+\(([^)]+)\)\s*(\*)?
Что происходит следующим образом.
Фиксированная строка "Идентификатор схемы:":
Scheme ID:
Далее следуют один или несколько символов a-z, 0-9 или -. Мы используем скобки, чтобы зафиксировать его как $1:
([a-z0-9-]+)
Далее следуют один или несколько пробельных символов:
\s+
Затем следует открывающая скобка (которую мы избегаем), за которой следует любое количество символов, которые не являются закрытой скобкой, а затем закрывающая скобка (экранированная). Мы используем невыпадающие скобки для захвата слов в виде $2:
\(([^)]+)\)
Далее следуют некоторые пробелы, возможно, a *, зафиксированные как $3:
\s*(\*)?
Ответ 2
Вы можете использовать регулярное выражение, например следующее:
/([-a-z0-9]+)\s*\((.*?)\)\s*(\*)?/
Итак, например:
$s = "abc-456-hu5t10 (High priority) *";
$s =~ /([-a-z0-9]+)\s*\((.*?)\)\s*(\*)?/;
print "$1\n$2\n$3\n";
печатает
abc-456-hu5t10
High priority
*
Ответ 3
(\S*)\s*\((.*?)\)\s*(\*?)
(\S*) picks up anything which is NOT whitespace
\s* 0 or more whitespace characters
\( a literal open parenthesis
(.*?) anything, non-greedy so stops on first occurrence of...
\) a literal close parenthesis
\s* 0 or more whitespace characters
(\*?) 0 or 1 occurances of literal *
Ответ 4
Долгое время нет Perl
while(<STDIN>) {
next unless /:\s*(\S+)\s+\(([^\)]+)\)\s*(\*?)/;
print "|$1|$2|$3|\n";
}
Ответ 5
Ну, один лайнер здесь:
perl -lne 'm|Scheme ID:\s+(.*?)\s+\((.*?)\)\s?(\*)?|g&&print "$1:$2:$3"' file.txt
Развернуто до простого script, чтобы немного объяснить ситуацию:
#!/usr/bin/perl -ln
#-w : warnings
#-l : print newline after every print
#-n : apply script body to stdin or files listed at commandline, dont print $_
use strict; #always do this.
my $regex = qr{ # precompile regex
Scheme\ ID: # to match beginning of line.
\s+ # 1 or more whitespace
(.*?) # Non greedy match of all characters up to
\s+ # 1 or more whitespace
\( # parenthesis literal
(.*?) # non-greedy match to the next
\) # closing literal parenthesis
\s* # 0 or more whitespace (trailing * is optional)
(\*)? # 0 or 1 literal *s
}x; #x switch allows whitespace in regex to allow documentation.
#values trapped in $1 $2 $3, so do whatever you need to:
#Perl lets you use any characters as delimiters, i like pipes because
#they reduce the amount of escaping when using file paths
m|$regex| && print "$1 : $2 : $3";
#alternatively if(m|$regex|) {doOne($1); doTwo($2) ... }
Хотя если бы это было что-то другое, кроме форматирования, я бы использовал основной цикл для обработки файлов и извлечения тела script вместо того, чтобы полагаться на ключи командной строки для цикла.
Ответ 6
Для этого требуется небольшое изменение в моем последнем ответе:
my ($guid, $scheme, $star) = $line =~ m{
The [ ] Scheme [ ] GUID: [ ]
([a-zA-Z0-9-]+) #capture the guid
[ ]
\( (.+) \) #capture the scheme
(?:
[ ]
([*]) #capture the star
)? #if it exists
}x;
Ответ 7
Строка 1:
$input =~ /'^\S+'/;
$s1 = $&;
Строка 2:
$input =~ /\(.*\)/;
$s2 = $&;
Строка 3:
$input =~ /\*?$/;
$s3 = $&;