Я ищу решение к разделению строки, которая содержит текст в следующем формате:
"abcd efgh 'ijklm no pqrs' tuv"
который приведет к следующим результатам:
['abcd', 'efgh', 'ijklm no pqrs', 'tuv']
Другими словами, это разделяет пробелом если в единственной заключенной в кавычки строке. Я думаю, что это могло быть сделано с.NET regexps использование операторов "Lookaround", особенно балансируя операторы. Я не так уверен в Perl.
Используйте Text::ParseWords:
#!/usr/bin/perl
use strict; use warnings;
use Text::ParseWords;
my @words = parse_line('\s+', 0, "abcd efgh 'ijklm no pqrs' tuv");
use Data::Dumper;
print Dumper \@words;
Выход:
C:\Temp> ff $VAR1 = [ 'abcd', 'efgh', 'ijklm no pqrs', 'tuv' ];
Вы можете посмотреть исходный код для Text::ParseWords::parse_line
, чтобы увидеть используемый шаблон.
Итак, вы решили использовать регулярное выражение? Теперь у вас две проблемы.
Позвольте мне сделать небольшой вывод. Вам нужно произвольное количество полей, где поле состоит из текста без пробелов или разделено пробелами и начинается с кавычки и заканчивается кавычкой (возможно, с пробелами между ними).
Другими словами, вы хотите делать то, что делает оболочка командной строки. Вам действительно стоит просто использовать что-то повторно. В противном случае вы должны захватывать поле за раз с помощью регулярного выражения, например:
^ *([^ ]+|'[^']*')(.*)
Где вы добавляете группу один в свой список и продолжаете цикл с содержимым группы 2.
Один проход через регулярное выражение не сможет захватить сколь угодно большое количество полей. Возможно, вы сможете разделить на регулярное выражение (python сделает это, не уверен в perl), но поскольку вы сопоставляете материал за пределами пробелов, я не уверен, что это вообще вариант.
use strict; use warnings;
my $text = "abcd efgh 'ijklm no pqrs' tuv 'xwyz 1234 9999' 'blah'";
my @out;
my @parts = split /'/, $text;
for ( my $i = 1; $i < $#parts; $i += 2 ) {
push @out, split( /\s+/, $parts[$i - 1] ), $parts[$i];
}
push @out, $parts[-1];
use Data::Dumper;
print Dumper \@out;