perl регулярное выражение для получения запятой не в круглых или вложенных скобках - PullRequest
2 голосов
/ 09 января 2020

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

a   ,   (b)  ,   (d$_,c)    ,     ((,),d,(,))

Запятые между a и (b), (b ) и (d $ , c), (d $ , c) и ((,), d, (,)) должны совпадать, но не внутри (d $ _, c) ) или ((,), d, (,)).

Примечание. В конце концов я хочу разделить строку этими запятыми.

Попробовал это регулярное выражение: (?!<(?:\(|\[)[^)\]]+),(?![^(\[]+(?:\)|\])) из здесь но это работает только для не вложенных скобок.

Ответы [ 2 ]

4 голосов
/ 09 января 2020

Вы можете использовать

(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|,

См. Демоверсию regex

Подробности

  • (\((?:[^()]++|(?1))*\)) - Группа захвата 1: соответствует подстроке в сбалансированных скобках:
    • \( - ( char
    • (?:[^()]++|(?1))* - ноль или более вхождений 1+ символов, отличных от ( и ) или весь шаблон группы 1 (из-за подпрограммы regex (?1), которая необходима здесь, поскольку рекурсивна только часть всего шаблона регулярного выражения)
    • \) - ) char.
  • (*SKIP)(*F) - пропускает найденное совпадение и начинает следующий поиск с конца совпадения
  • | - или
  • , - соответствует запятой вне вложенных скобок.
1 голос
/ 09 января 2020

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

use strict;
use warnings;

my $str = 'a   ,   (b)  ,   (d$_,c)    ,     ((,),d,(,))';

my $nesting = 0;
my $buffer = '';
my @vals;
while ($str =~ m/\G([,()]|[^,()]+)/g) {
  my $token = $1;
  if ($token eq ',' and !$nesting) {
    push @vals, $buffer;
    $buffer = '';
  } else {
    $buffer .= $token;
    if ($token eq '(') {
      $nesting++;
    } elsif ($token eq ')') {
      $nesting--;
    }
  }
}
push @vals, $buffer if length $buffer;

print "$_\n" for @vals;

Вы можете использовать Parser :: MG C для создания такого синтаксического анализатора более абстрактно.

...