Как я могу разделить строку пробелом если в единственной заключенной в кавычки строке?

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

"abcd efgh 'ijklm no pqrs' tuv"

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

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

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

5
задан Sinan Ünür 17 March 2010 в 03:36
поделиться

3 ответа

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

15
ответ дан 18 December 2019 в 07:53
поделиться

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

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

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

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

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

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

2
ответ дан 18 December 2019 в 07:53
поделиться
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;
3
ответ дан 18 December 2019 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: