2009-05-27 2 views
2

Если мне дано в Perl, могу ли я узнать, сколько у них скобок? Так, например:Как узнать, сколько захватных скобок находится в Perl regexp?

\w  -> 0 
(\w)  -> 1 
(\w(\w)) -> 2 
+0

Это поможет, если вы могли бы сказать нам, почему вам нужна эта информация - то есть то, что вы собираетесь использовать его для. – 2009-05-27 10:32:54

ответ

1

Есть два специальных массива @ - и @ +, содержащие начальные позиции и конечные позиции успешных матчей. Используйте длину массива при согласовании.

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

+1

Несвободные открывающие скобки БЕЗ «?:» следуют за ними, так как (?: text) не записывается. –

+0

Использование массива @ - дает мне информацию, которую я хочу. – justintime

+0

Скорее поздно, чтобы принять anwser. Когда я отправил сообщение, я был новичком в SO и не выработал прием сообщений. – justintime

4

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

С другой стороны, если вы хотите знать, как спички есть вы бы лучше выполнения регулярного выражения в контексте списка:

my @matches = $string_to_match_on =~ /(\w(\w))/; 

Размер списка даст вам количество совпадений :

my $count = @matches; 

(в виде списка или массива в скалярном контексте задается размер списка или массива).

+0

Я пытаюсь выяснить количество захватов (возможные совпадения). Я опасаюсь подсчитывать скобки как из-за краевых случаев, таких как «\\ (" или [(] – justintime

+0

Возможно, вам, вероятно, нужен «правильный» парсер, такой как Text :: Balanced или вы можете бросить осторожность на ветер и пишите один из них с помощью Parse :: RecDescent. Вы правы, что скобки подсчета вряд ли будут работать большую часть времени. Имеете ли вы дело с регулярными выражениями в качестве входных данных для вашего кода? –

1

Это не совсем тривиально, поскольку не все круглые скобки не захватываются - например (?: ...), (? = ...) и так далее.

Вообще, помните, что вы всегда можете:

my @catch_all = $string =~ m/......................./; 

, а затем просто проверить @catch_all;

+0

Если я это сделаю, как объяснить разницу между регулярным выражением без захвата и неудачей совпадения. – justintime

+0

Если совпадение совпадений, пустой список всегда возвращается. Если совпадение выполнено успешно, список будет содержать одно число «1», если скобки не будут скопированы. В зависимости от того, что вы делаете, вы также можете найти именованные захваты полезными. На них есть Perl-tip на http://perltraining.com.au/tips/2008-02-08.html – pjf

2

Важно знать, зачем вам это нужно.

YAPE::Regex help?

Edit: Вот демонстрация:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper; 
use YAPE::Regex; 

my $regex = qr/^(A)(B)(C)[0-9]+(\w+)$/; 

my $parser = YAPE::Regex->new($regex); 

my $n_captures; 

while (my $node = $parser->next) { 
    if ($parser->state =~ /^capture\(([0-9]+)\)$/) { 
     $n_captures = $1; 
    } 
} 

print "$n_captures\n"; 


C:\Temp> t 
4 
Смежные вопросы