Как найти несколько шаблонов регулярных выражений одним способом с помощью Perl - PullRequest
0 голосов
/ 04 мая 2018

Вопрос обновлен

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

([a-z]+)(\d+)
\}([a-z]+)
([a-z]+)(\+|\-)
([0-9])\](\+|\-)
...
...

мой входной файл как:

\ce{CO2}  
\ce{2CO}  
\ce{H2O}  
\ce{Sb2O3}  
...
...    

В моем коде я нахожу все шаблоны регулярных выражений, такие как

if($string=~m/([a-z]+)(\d+)/g) {  my statements ... }
if($string=~m/\}([a-z]+)/g) {  my statements ... }
if($string=~m/([a-z]+)(\+|\-)/g) {  my statements ... }
if($string=~m/([0-9])\](\+|\-)/g) {  my statements ... }

Вместо выполнения приведенного выше кода Есть ли другой способ упростить код?

Не могли бы вы, кто-нибудь, поделитесь своими мыслями о моем улучшении для лучшего кодирования.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

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

Я делаю следующие предположения

  • Требуются все совпадения
  • код может быть одинарным или двойным
  • обе группы записаны в одну строку

Я думаю, что вы хотите

while ( $string =~ /(([a-z]+)(\d+)|\}([a-z]+)|([a-z]+)(\+|\-)|([0-9])\](\+|\-))/g )
{
#$1 has the whole match
#$2 has the first group if defined
#$3 has the second group if defined
}

Однако я предпочитаю метод ниже. это будет захватывать в одну строку

while ($string =~ /([a-z]+\d+|\}[a-z]+|[a-z]+\+|\-|[0-9]\]\+|\-)/g ) 
{
# in here split the match if required
}

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

, если вы хотите просто один матч, используйте

if(
$string=~m/([a-z]+)(\d+)/   ||
$string=~m/\}([a-z]+)/      ||
$string=~m/([a-z]+)(\+|\-)/ ||
$string=~m/([0-9])\](\+|\-)/ 
)
{
#some code
}
0 голосов
/ 04 мая 2018

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

Когда вы обрабатываете данные динамически, типичным подходом является использование таблицы отправки . Мы можем сделать что-то подобное здесь. Часто для этого используется ссылка на хеш или хэш, но поскольку нам нужен определенный порядок, вместо этого я буду использовать массив.

my @dispatch = (
    {
        pattern => qr/f(o)(o)/,
        callback => sub {
            my ($one, $two) = @_;
            print "Found $one and $two\n";
        },
    },
    {
        pattern => qr/(bar)/,
        callback => sub {
            my $capture = shift;
            print "Saw $capture";
        },
    },
);

Это в основном список шаблонов поиска и связанных с ним инструкций. Каждый шаблон имеет обратный вызов , который является ссылкой на код. Я решил, что имеет смысл передать переменные захвата, потому что в ваших шаблонах есть группы захвата.

Теперь, чтобы вызвать их, мы выполняем итерацию по массиву диспетчеризации, сопоставляем шаблон и затем вызываем соответствующий обратный вызов, передавая все захваты.

my $text = "Foo bar foo bar baz.";

foreach my $search (@dispatch) {
    if ($text =~ $search->{pattern}) {
        $search->{callback}->(@{^CAPTURE}); # this requires Perl 5.26
    }
}

Обратите внимание, что я использую @{^CAPTURE}, который был добавлен в Perl в версии 5.25.7, поэтому вам потребуется по крайней мере стабильный релиз Perl 5.26 , чтобы использовать его , (На старых Perl my @capture = $t =~ $search->{pattern} и $search->{callback}->(@capture) будут вести себя аналогично).

Это намного элегантнее, чем иметь список операторов if () {}, потому что его очень легко расширять. Таблица отправки может быть создана на лету, на основе некоторого ввода или полностью считана с диска.

Когда мы запускаем этот код, он создает следующий вывод

Found o and o
Saw bar

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

Если вы хотите узнать больше о таблицах рассылки, я предлагаю вам прочитать вторую главу Отличная книга Марка Джейсона Доминуса Perl высшего порядка , которая доступна бесплатно как PDF на его сайте.

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