Как я могу разделить строку по пробелу, если она не внутри строки в кавычках? - PullRequest
5 голосов
/ 17 марта 2010

Я ищу решение для разделения строки, которая содержит текст в следующем формате:

"abcd efgh 'ijklm no pqrs' tuv"

, который даст следующие результаты:

['abcd', 'efgh', 'ijklm no pqrs', 'tuv']

Другими словами, он разделяется на пробелы, если только внутри одной строки в кавычках. Я думаю, что это можно сделать с помощью регулярных выражений .NET, используя операторы «Lookaround», особенно операторы балансировки. Я не так уверен насчет Perl.

Ответы [ 3 ]

15 голосов
/ 17 марта 2010

Использовать Текст :: 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, чтобы увидеть используемый шаблон.

3 голосов
/ 17 марта 2010
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;
2 голосов
/ 17 марта 2010

Итак, вы решили использовать регулярное выражение? Теперь у вас есть две проблемы.

Позвольте мне сделать вывод немного. Требуется произвольное количество полей, где поле состоит из текста без пробелов, или оно разделено пробелами и начинается с кавычки и заканчивается кавычкой (возможно, с пробелами между).

Другими словами, вы хотите сделать то, что делает оболочка командной строки. Вы действительно должны просто что-то использовать. В противном случае вы должны захватывать поле за раз с регулярным выражением, например:

^ *([^ ]+|'[^']*')(.*)

Когда вы добавляете группу один к своему списку и продолжаете цикл с содержанием группы 2.

Один проход через регулярное выражение не сможет захватить сколь угодно большое количество полей. Возможно, вам удастся разделить регулярное выражение (Python сделает это, но не уверен насчет perl), но, поскольку вы сопоставляете вещи вне пробелов, я не уверен, что это даже вариант.

...