RegEx - Индексированные / Массив именованных групп захвата? - PullRequest
3 голосов
/ 14 июня 2010

У меня есть ситуация, когда что-то может выглядеть в следующем формате:

---id-H--
Header: data
Another Header: more data
Message: sdasdasdasd
Message: asdasdasdasd
Message: asdasdasd

Может быть много сообщений или просто пара. Я бы предпочел не выходить за пределы RegEx, потому что я использую RegEx для анализа некоторой информации заголовка над сообщениями, и сообщения вместе с заголовками являются частью текста, который я анализирую. Вложенных в текст сообщений может быть много.

Я также хотел бы использовать именованные группы захвата, так что-то вроде

Message: (?<Message[index of match]>.+)

, где совпадает столько раз, сколько может с заполненным индексом. Существует ли что-нибудь подобное в RegEx? (Я в конечном итоге буду использовать это в Perl.)

Ответы [ 2 ]

3 голосов
/ 14 июня 2010

Если каждая группа отделена пустой строкой, это может приблизить вас:

use strict;
use warnings;

# use two lines as the "line" separator
local $/ = "\n\n";

while (my $line = <DATA>)
{
    my ($id) = ($line =~ /^---id-(\d+)--$/m);
    my @messages = ($line =~ /^Message: (.*)$/mg);

    print "On line $id, found these messages: ", join(', ', @messages), "\n";
}
__DATA__
---id-1--
Header: data
Another Header: more data
Message: sdasdasdasd
Message: asdasdasdasd
Message: asdasdasd

---id-2--
Header: data2
Another Header: stuff
Message: more message
Message: another message
Message: YAM

Бег, который дает:

On line 1, found these messages: sdasdasdasd, asdasdasdasd, asdasdasd  
On line 2, found these messages: more message, another message, YAM  
2 голосов
/ 14 июня 2010

Синтаксис именованного буфера захвата Perl, где у вас есть (?<name>...), действительно является заменой или альтернативным использованием синтаксиса Perl /(pattern1(pattern2))/ с потенциальной неоднозначностью того, какой буфер захвата какой.

Вы можете получить хешированную форму совпадения (?<name>pattern), затем обратиться к специальным значениям хеша %+ и %- См. perlre для синтаксиса именованного буфера захвата и perlvar для примера% + и% - и именованных захватов.

Однако в Perl есть гораздо более простые решения.Вы можете выполнить глобальное сопоставление, которое возвращает список, а затем работать со списком.Вы сопоставляете все в массив.

Вот примеры:

foreach my $message ($text=~/^Message: (.*)/gm) {
   # Process messages...
}

или

my @messages = ($text=~/^Message: (.*)/gm);
print "The first message is $messages[0]\n";

Есть много других способов, но эти 2 являются общими и Perly

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...