perl разбивает строку

Я понимаю, что не сделал название достаточно хорошим, но я не становлюсь лучше.

Предположим, что есть строка

$str = "(aa)(bb)(cc)(dd)(ee)";

То есть есть подстроки, заключенные в круглые скобки, пробела между скобочными группами нет, т.е. как ()(), но внутри круглой скобки, где я написал aa, bb, cc и т.д., могут быть пробелы. Скобки могут быть вложенными, но это не совсем важно. но есть неизвестное количество скобочных групп.

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

# @arr contains now ("(aa)", "(bb)", "(cc)" .. etc)

конечно, я могу реализовать метод, основанный на счетчике, но разве perl, будучи perl, не имеет встроенных методов для этого? Я не совсем знаю, как называется эта конкретная операция, поэтому я не знаю, что искать, разделение строк слишком общее, не так ли?

редактировать: разделение строки с разделителями в скобках в perl ‹ --- поиск этого не возвращает мне ничего полезного, я думаю, это связано с тем, что на самом деле это не DELIMITED, заключенный?


person Sean    schedule 08.02.2014    source источник
comment
Что вы пробовали до сих пор. Stackoverflow не является сервисом для написания кода, но его участники будут рады помочь вам улучшить ваши собственные попытки. Кроме того, приведите пример того, как вы хотите обрабатывать вложенные скобки.   -  person AdrianHHH    schedule 08.02.2014
comment
как я уже сказал, у меня есть реализация на основе счетчика, и я спрашиваю, есть ли в Perl уже встроенная функция или инструкция для этого. Я был бы рад любой подсказке, я не совсем просил услугу написания кода (должно быть, мой плохой английский). Что касается вложенных элементов, я хочу извлечь их сбалансированным образом, то есть (a(bb)c)(dd) создаст (a(bb)c) и (dd), то есть единственное сбалансированное извлечение, нет?   -  person Sean    schedule 08.02.2014


Ответы (3)


@arr= map { "$_)" } split /\)/, $str;

Этот метод удаляет закрывающую скобку, но затем добавляет ее обратно.

Другой способ — использовать флаг «глобальный» в регулярном выражении, который возвращает все совпадения.

@arr= ( $str =~ /\([^)]*\)/g )
person dataless    schedule 08.02.2014
comment
ах, глобальный флаг, это хорошо, спасибо, сейчас проверю - person Sean; 08.02.2014
comment
Теперь я вижу, что вы также хотели совместить вложенные круглые скобки... Другие вопросы здесь ответили, как их написать. См. stackoverflow.com /вопросы/12719935/ - person dataless; 08.02.2014
comment
спасибо вам обоим, вариант g сработал идеально. поэтому я выберу этот ответ в качестве ответа, так как он был первым. - person Sean; 08.02.2014

Есть несколько предложений.

Например первый:

use strict;

my $str = "(aa)(bb)(cc)(dd)(ee)";
my @arr;

while ($str =~ /(\(.*?\))/ig) {
    push @arr, $1;
};
person Alex_Crack    schedule 08.02.2014

Если мы проигнорируем вложенность, то, что вы хотите сделать, будет разделено между ) и (.

my @arr = split /(?<=\()(?=\()/, $str;

Вместо разделения вы также можете извлечь части.

my @arr = $str =~ /( \( [^()]* \) )/xg;

Сопоставление вложенных скобок — это просто вопрос рекурсивного применения этого шаблона регулярного выражения.

my @arr = $str =~ /\G ( \( (?: [^()]++ | (?1) )* \) )/xg;
person ikegami    schedule 08.02.2014