2016-10-05 5 views
2

Там будет строка «-test аааа -machine ГЭБ -из ссс»

Как извлечь «АААА», «БББ», «ссс», используя регулярные?

Даже строка "-из       ссс       -test         аааа         -machine БББ"
(Различный порядок, несколько пространство ....)Извлечение данных из строки по Perl

Я имел пробовал какой-то код, но всегда получал недопустимые данные.

$str = "-test aaaa  -machine bbb -from ccc"; 
$str =~ /-test\s*(.*)\s*/; 

печати

aaaa -machine bbb -from ccc 

Я также хочу, чтобы справиться с НИЖЕ случай

-test aa_aa -machine aab-baa-aba -from ccc 
+1

Это будет работать для тестовых данных: 'Perl -e«использовать строгий; использовать предупреждения; my $ str = "-test aaaa -machine bbb-from ccc"; while ($ str = ~ m/(\ w +)/g) {print $ 1. "\ n"; } '' – AbhiNickz

ответ

1
my @matches; 
my $regex = qr/-\w+\s+([\w-]+)/; 

my $string = q{-test aaaa -machine bbb -from ccc}; 
@matches = $string =~ /$regex/g; 
print "Matches for first string are: @matches\n"; 

my $other_string = q{-from ccc -test aaaa -machine bbb}; 
@matches = $other_string =~ /$regex/g; 
print "Matches for second string are: @matches\n"; 

my $third_string = q{-test aa_aa -machine aab-baa-aba -from ccc}; 
@matches = $third_string =~ /$regex/g; 

print "Matches for third string are: @matches"; 
+0

Большое спасибо ... Но если какой-то символ в таких данных, как« -test aa_aa -machine aab-baa-aba-from ccc ». Как правильно получить данные? – Sai

+0

Спасибо за ваш ответ – Sai

7

Вы не должны использовать регулярное выражение, вы можете использовать хэш что.

use strict; 
use warnings; 
use Data::Dumper; 

my $str = '-test aaaa -machine bbb -from ccc'; 
my %field = split ' ', $str; 
print Dumper(\%field); 

Выход:

$VAR1 = { 
      '-from' => 'ccc', 
      '-machine' => 'bbb', 
      '-test' => 'aaaa' 
     }; 

Независимо от того, что порядок есть, split возвращает массив пар (в форме [word1, word2, word3, word4, word5, word6] и word1, word3, word5 будет -field_name), что при присвоении хэш, создает его таким образом, что теперь, если вы хотите получить строку после -test, например, вы просто получите к ней доступ, набрав $field{"-test"} и сделайте все, что хотите.

EDIT: Не имеет значения, сколько пробелов у вас есть между словами или символами в словах. Он работает одинаково для всех случаев, если вы храните его в формате -some_field something -another_field another_thing ...

+0

Спасибо. Я никогда не думал о «расколе». Это хороший выбор =) – Sai

6

Я собираюсь ответить на вопрос, который (я думаю) лежит в основе вашего вопроса - не вопрос, который вы задали.

Мне кажется, что вы разбираете параметры командной строки. Поэтому используйте синтаксический анализатор командной строки, а не заново для этого. Getopt::Long является частью стандартного дистрибутива Perl.

#!/usr/bin/perl 

use strict; 
use warnings; 
# We use modern Perl (here, specifically, say()) 
use 5.010; 

use Getopt::Long 'GetOptionsFromString'; 
use Data::Dumper; 

my %options; 

my $str = '-test aa_aa -machine aab-baa-aba -from ccc'; 
GetOptionsFromString($str, \%options, 'test=s', 'machine=s', 'from=s'); 

say Dumper \%options; 

Как правило, вы будете использовать функцию GetOptions(), как вы разбираете параметры командной строки, которые доступны в @ARGV. Я не уверен, как параметры оказались в вашей строке, но для этой ситуации есть полезная функция GetOptionsFromString().

Обновление: Чтобы объяснить, почему ваш код не работает.

$str = "-test aa_aa  -machine aab-baa-aba -from ccc"; 
$str =~ /-test\s*(.*)\s*/; 

Вы захватывая, что соответствует (.*). Но .* жадный. То есть, он соответствует как можно большему количеству данных.И в этом случае это означает, что он соответствует до конца строки. Есть (по крайней мере!) Несколько способов исправить это.

1/Сделать матч не жадным, добавив ?.

$str =~ /-test\s*(.*?)\s*/; 

2/Более подробно о том, что вы ищете, - в этом случае не-пробельные символы.

$str =~ /-test\s*(\S*)\s*/; 
+0

Прохладный ... Спасибо за ваше объяснение. Это так хорошо для меня ... – Sai

-2

Это должно сделать трюк

$str = "-test aa_aa  -machine aab-baa-aba -from ccc"; 
($test,$machine,$from) = $str =~ /\-test(.+)\-machine(.+)\-from(.+)/; 

print "Test: $test, Machine: $machine, From: $from"; 
+0

Порядок '-test',' -machine' и '-form' в строке может измениться (как объяснение в вопросе), и в этом случае ваше решение не будет работать. Кроме того, вы также захватываете белые пробелы с помощью '. +', Что не идеально. И если добавить дополнительный параметр, он будет зафиксирован как значение одного из предыдущих параметров. Кроме того, нет необходимости скрывать '-' в регулярном выражении (за исключением иногда внутри' [...] '. – Dada

Смежные вопросы