in reply to Same problem replacing array index numbers

Reading your 'duplicate' post, I'm not quite sure what you are trying to achieve there. As to this post, the example below may be of interest. I think it should be suitable for either line-by-line or whole-file processing. 5.10+ needed due to use of  \K operator.

BTW: In addition to the problems with the code in this post pointed out by JavaFan, I would add that  int rand 9999 will only produce numbers in the range 0 .. 9998. I don't know if this was intended or not.

>perl -wMstrict -le "my $s = 'xx @ra[1] y @ara[23] z @ra[1] aa @ara[23] b @ra[1] @ara[23]'; print qq{'$s'}; ;; my %found; $s =~ s{ \@ ([a-z] [a-z\d_]* \[) \K (\d+) (?= \]) } { $found{$1 . $2} //= int rand 9999; }xmsge; print qq{'$s'}; " 'xx @ra[1] y @ara[23] z @ra[1] aa @ara[23] b @ra[1] @ara[23]' 'xx @ra[2038] y @ara[6310] z @ra[2038] aa @ara[6310] b @ra[2038] @ara[ +6310]'

Update: Used  //= instead of  ||= in substitution replacement block code per Anonymonk's usage below.

Replies are listed 'Best First'.
Re^2: Same problem replacing array index numbers
by Anonymous Monk on Apr 11, 2012 at 18:10 UTC
    Please let me to improve your code:
    my $s = 'xx @ra[1] y @ara[23] z @ra[1] aa @ara[23] b @ra[1] @ara[23]'; print qq{'$s'\n}; my %found; my %generated; $s =~ s{ \@ ([a-z] [a-z\d_]* \[) \K (\d+) (?= \]) } { $found{"$1$2"} //= do { my $rand; do {$rand = int rand 9999} while exists $generated{$rand}; $generated{$rand} = (); $rand; }; }xmsge; print qq{'$s'\n};
    Fixed issues of producing something like this:
    'xx @ra[1] y @ara[23] z @ra[1] aa @ara[23] b @ra[1] @ara[23]' 'xx @ra[1] y @ara[0] z @ra[1] aa @ara[2] b @ra[1] @ara[2]'
      ... producing something like this:
      'xx @ra[1] y @ara[23] z @ra[1] aa @ara[23] b @ra[1] @ara[23]'
      'xx @ra[1] y@ara[0] z @ra[1] aa@ara[2] b @ra[1] @ara[2]'

      Good catch on the use of  //= versus  ||= in your code since the value of the generated random integer could, indeed, be zero leading to a redefinition on a subsequent encounter. I would quibble with
          $generated{$rand} = ();
      however, since assigning the contents of an empty list to a scalar (i.e., undef) is very odd and likely to be confusing, it is much better, IMO, to assign 1 (or any true value) since that would slightly simplify the existence test to
          do { ... } while $generated{$rand};
      (if, in fact, there is a requirement that the generated random integers be non-repeating).

      ow.. cool.. could i also use a modified version of that to replace the array names to like a random string? i tried it myself but i cant replace with a string, only numbers...