Perl Chèn chuỗi vào url tại các địa điểm cụ thể (Perl Inserting string into a url at specific places)


問題描述

Perl Chèn chuỗi vào url tại các địa điểm cụ thể (Perl Inserting string into a url at specific places)

I have the following piece of code:

#!/usr/bin/perl

use strict;
use warnings;
#use diagnostics;

use URI qw( );

my @insert_words = qw(HELLO GOODBYE);  

while (<DATA>) {
   chomp;
   my $url = URI‑>new($_);
   my $query = $url‑>query;

foreach (@insert_words) {
  # Use package vars to communicate with /(?{})/ blocks.
  local our $insert_word = $_;

  local our @queries;
  if (defined $query) {
      $query =~ m{
          ^(.*[/=])([^/=&]*)((?:[/=&].*)?)\z
          (?{
              if (length $2) {
            push @queries, "$1$insert_word$2$3";
                  push @queries, "$1$insert_word$3";
                  push @queries, "$1$2$insert_word$3";
              }
          })
          (?!)
      }x;
  }

      if (@queries) {
          for (@queries) {
              $url‑>query($_);
              print $url, "\n";
          }
      }
      else {
          print $url, "\n";
      }
  }
}


__DATA__
http://www.example.com/index.php?route=9&other=7

The above piece of code works correctly and produces the following output:

http://www.example.com/index.php?route=9&other=HELLO7
http://www.example.com/index.php?route=9&other=HELLO
http://www.example.com/index.php?route=9&other=7HELLO
http://www.example.com/index.php?route=HELLO9&other=7
http://www.example.com/index.php?route=HELLO&other=7
http://www.example.com/index.php?route=9HELLO&other=7
http://www.example.com/index.php?route=9&other=GOODBYE7
http://www.example.com/index.php?route=9&other=GOODBYE
http://www.example.com/index.php?route=9&other=7GOODBYE
http://www.example.com/index.php?route=GOODBYE9&other=7
http://www.example.com/index.php?route=GOODBYE&other=7
http://www.example.com/index.php?route=9GOODBYE&other=7

As you can see it inserts the words in the array at specific places in the url.

What I am now having problems with:

I would now like to add the functionality to do all the possible combinations of HELLO and GOODBYE (or whatever is in the @insert_words) as well, for example it should also add the following url's to the output I already get:

http://www.example.com/index.php?route=HELLO&other=GOODBYE
http://www.example.com/index.php?route=HELLO&other=HELLO
http://www.example.com/index.php?route=GOODBYE&other=HELLO
http://www.example.com/index.php?route=GOODBYE&other=GOODBYE

But I do not know how to go about this in the best way?

Your help with this will be much appreciated, many thanks


參考解法

方法 1:

Please don't use fancy regexes like that ‑ they are an experimental feature of Perl and are far from simple to comprehend.

If I understand you then you need to do this recursively.

I think you want all variations of the URL with each query parameter as it is, or preceded, succeeded, or replaced by every value in @insert_words.

This seems to do what you ask. It uses URI::QueryParam to split up the query portion of the URL properly instead of using your nasty regex. It does produce substantially more combinations than you show in your question but I can see no other way of interpreting your requirement.

The number of possible variations is 49. Each parameter can have its original value, or be preceded, succeeded or replaced by either of two values. That is seven possible values for each parameter and so 7² or 49 different variations for two parameters.

use strict;
use warnings;

use URI;
use URI::QueryParam;

my @insert_words = qw/ HELLO GOODBYE /;

my @urls;

sub mod_param {
    my ($url, $paridx, @insertions) = @_;

    my @params = $url‑>query_param;
    return if $paridx > $#params;

    my $key = $params[$paridx];
    my $oldval = $url‑>query_param($key);

    my @variations = ($oldval);
    push @variations, ($oldval.$_, $_.$oldval, $_) for @insertions;

    for my $val (@variations) {
        $url‑>query_param($key, $val);
        if ($paridx == $#params) {
          push @urls, "$url";
        }
        else {
          mod_param($url, $paridx + 1, @insertions);
        }
    }
    $url‑>query_param($key, $oldval);
}

while (<DATA>) {
    chomp;
    my $url = URI‑>new($_);
    @urls = ();
    mod_param($url, 0, @insert_words);
    print $_, "\n" for @urls;
}

__DATA__
http://www.example.com/index.php?route=9&other=7

output

http://www.example.com/index.php?route=9&other=7
http://www.example.com/index.php?route=9&other=7HELLO
http://www.example.com/index.php?route=9&other=HELLO7
http://www.example.com/index.php?route=9&other=HELLO
http://www.example.com/index.php?route=9&other=7GOODBYE
http://www.example.com/index.php?route=9&other=GOODBYE7
http://www.example.com/index.php?route=9&other=GOODBYE
http://www.example.com/index.php?route=9HELLO&other=7
http://www.example.com/index.php?route=9HELLO&other=7HELLO
http://www.example.com/index.php?route=9HELLO&other=HELLO7
http://www.example.com/index.php?route=9HELLO&other=HELLO
http://www.example.com/index.php?route=9HELLO&other=7GOODBYE
http://www.example.com/index.php?route=9HELLO&other=GOODBYE7
http://www.example.com/index.php?route=9HELLO&other=GOODBYE
http://www.example.com/index.php?route=HELLO9&other=7
http://www.example.com/index.php?route=HELLO9&other=7HELLO
http://www.example.com/index.php?route=HELLO9&other=HELLO7
http://www.example.com/index.php?route=HELLO9&other=HELLO
http://www.example.com/index.php?route=HELLO9&other=7GOODBYE
http://www.example.com/index.php?route=HELLO9&other=GOODBYE7
http://www.example.com/index.php?route=HELLO9&other=GOODBYE
http://www.example.com/index.php?route=HELLO&other=7
http://www.example.com/index.php?route=HELLO&other=7HELLO
http://www.example.com/index.php?route=HELLO&other=HELLO7
http://www.example.com/index.php?route=HELLO&other=HELLO
http://www.example.com/index.php?route=HELLO&other=7GOODBYE
http://www.example.com/index.php?route=HELLO&other=GOODBYE7
http://www.example.com/index.php?route=HELLO&other=GOODBYE
http://www.example.com/index.php?route=9GOODBYE&other=7
http://www.example.com/index.php?route=9GOODBYE&other=7HELLO
http://www.example.com/index.php?route=9GOODBYE&other=HELLO7
http://www.example.com/index.php?route=9GOODBYE&other=HELLO
http://www.example.com/index.php?route=9GOODBYE&other=7GOODBYE
http://www.example.com/index.php?route=9GOODBYE&other=GOODBYE7
http://www.example.com/index.php?route=9GOODBYE&other=GOODBYE
http://www.example.com/index.php?route=GOODBYE9&other=7
http://www.example.com/index.php?route=GOODBYE9&other=7HELLO
http://www.example.com/index.php?route=GOODBYE9&other=HELLO7
http://www.example.com/index.php?route=GOODBYE9&other=HELLO
http://www.example.com/index.php?route=GOODBYE9&other=7GOODBYE
http://www.example.com/index.php?route=GOODBYE9&other=GOODBYE7
http://www.example.com/index.php?route=GOODBYE9&other=GOODBYE
http://www.example.com/index.php?route=GOODBYE&other=7
http://www.example.com/index.php?route=GOODBYE&other=7HELLO
http://www.example.com/index.php?route=GOODBYE&other=HELLO7
http://www.example.com/index.php?route=GOODBYE&other=HELLO
http://www.example.com/index.php?route=GOODBYE&other=7GOODBYE
http://www.example.com/index.php?route=GOODBYE&other=GOODBYE7
http://www.example.com/index.php?route=GOODBYE&other=GOODBYE

(by yonetpkbjiBorodin)

參考文件

  1. Perl Inserting string into a url at specific places (CC BY‑SA 3.0/4.0)

#perl #string #url #RegEx #Insert






相關問題

保持特定位數的簡單 Perl 數學 (simple Perl math while keeping a specific number of digits)

如何在 Windows 批處理腳本或 Perl 中將文件移動到回收站? (How can I move files to the Recycle Bin in a Windows batch script or Perl?)

從子程序返回數組 (Return array from subroutine)

我可以以與操作系統無關的方式限制 Perl 進程使用的內存嗎? (Can I Iimit the memory used by a Perl process in an OS-agnostic way?)

$# 在 perl 中接受什麼作為輸入? (what does $# accept as input in perl?)

Perl Text::CSV_XS 從字符串中讀取 (Perl Text::CSV_XS read from string)

使用 excel 2010 更新批處理文件中的變量 (use excel 2010 to update variables in batch file)

在 perl 中為哈希添加值 (Adding value to an hash in perl)

為什麼 perl 會忽略我的正則表達式中的多餘字符? (Why does perl ignore extra characters in my regex?)

boost::regex - \bb? (boost::regex - \bb?)

如果小於 X 天,如何從磁盤讀取文件,如果舊,則重新獲取 html 文件 (How to read a file from the disk if less than X days old, if older, refetch the html file)

使用 Devel-Cover 獲取覆蓋率報告 (Using Devel-Cover to get coverage reports)







留言討論