Обработка строки Perl qr RegEx в обратном направлении - PullRequest
1 голос
/ 08 февраля 2020

У меня есть серия строковых шаблонов qr // RegEx, соответствующих URL-адресам, поданным на мой сайт. Например, qr#^/safari/article/([0-9]+)\.html(\?(.*))?$#. Эта строка будет соответствовать пути из URL, например /safari/article/299.html?parameter=1. У меня есть отдельная подпрограмма, где я могу создавать URL-адреса для ссылки на различные части программы. Мне пришло в голову, что было бы неплохо, если бы эта последняя часть могла каким-то образом использовать вышеупомянутые шаблоны, которые я уже написал, - это уменьшило бы вероятность ошибки, если бы оба способа, с помощью которых были сгенерированы URL-адреса, и способ их последующей обработки происходили из одного и того же набор шаблонов.

Когда пользователь заходит на сайт, моя программа берет URL-адрес, предоставленный серверу, запускает его по строкам, подобным приведенным выше, и выводит $1 и $2 с шаблонами он находит (например, «299» и «параметр = 1», два параметра для загрузки страницы). По сути, теперь я хотел бы сделать это в обратном порядке и каким-то образом предоставить $1 и $2 и передать их в эту строку qr // для создания нового пути вывода (скажем, я бы установил $1 в "" 300 "и $2 to" parameter = 2 "каким-то образом объединить это со строкой qr // и получить вывод /safari/article/300.html?parameter=2.

Есть ли простой способ сделать что-то вроде" обратного регулярного выражения " «Похоже, что один из способов сделать это - просто сопоставить шаблон с регулярными выражениями с этими двумя шаблонами в скобках, но мне это кажется неаккуратным. Есть ли более чистый способ?

РЕДАКТИРОВАТЬ: Одной из причин хранения шаблонов в RegEx является то, что все они выбрасываются в многомерный массив для последующей обработки, которая может помочь выяснить, какой модуль следует вызывать. Вот пара примеров элементов:

 [
      { function => 'article', pattern => qr#^/safari/article/([0-9]+)\.html(\?(.*))?$#, weight => 106 },
      { function => 'topCommentedPosts', pattern => qr#^/safari/top\.html$#, weight => 100 }

 ]

1 Ответ

2 голосов
/ 08 февраля 2020

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

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $TEMPLATE = '/safari/article/$1.html?$2';

sub generate {
    my (@replacements) = @_;
    return $TEMPLATE =~ s/\$([12])/$replacements[$1-1]/gr
}

sub match {
    my ($string) = @_;
    my $regex = "$TEMPLATE";
    $regex =~ s/([?.])/\\$1/g;
    $regex =~ s/\$[0-9]+/(.*)/g;
    return $string =~ /$regex/
}

use Test::More;

is generate(300, 'parameter=2'), '/safari/article/300.html?parameter=2';

is_deeply [match('/safari/article/299.html?parameter=1')], [299, 'parameter=1'];

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