perl2newbie has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys, im trying to replace #<-(0N<-(s3T with *<-(0N<-(s3T

so im using: ...... foreach(@lines) { $_=~ $_ =~ s/\#<-(0N<-(s3T\/\*<-(0N<-(s3T/g; push(@newlines,$_); } ...
i get an error. 'unmatched < in regex......' Update: guys i got what i needed with: \Q search_string \E Can you please help. Thanks

Replies are listed 'Best First'.
Re: Find and Replace with special characters
by graff (Chancellor) on May 07, 2015 at 02:19 UTC
    The regex you showed us is using a backslash escape for "#" (which doesn't really need to be escaped), whereas you need escapes for open the parens. (Also, you're using a backslash in the replacement string, which would only be needed for getting a literal $ or @.)

    And maybe it's just a typo in your post, but you seem to be using the =~ operator twice, which seems wrong - since you're modifying $_, you don't need it at all.

    Yet another point: since you are only changing one character (# to *), you should use a "look-ahead assertion" for the other characters in the pattern.

    Finally, to top it off, you put a backslash escape in front of the forward-slash character that was supposed to be the middle delimiter for the "s///' operator, so perl only sees two of the three forward-slashes as delimiters.

    Try it like this:

    foreach ( @lines ) { s/#(?=<-\(0N<-\(s3T)/*/g; push(@newlines,$_); }
    (Update: Admittedly, using the look-ahead assertion in this case feels a bit uncomfortable, because you might get it confused with the look-behind syntax:
    /(?<=preceding_part)target_part/
      You also want to make up your mind on whether @lines is being modified in place. If so, then you don't need @newlines at all and it's just
      s/#(?=<-\(0N<-\(s3T)/*/g foreach ( @lines );
      Otherwise, if you need to keep both versions around, then it's
      @newlines = map { s/#(?=<-\(0N<-\(s3T)/*/gr } @lines;
      (it being somewhat more efficient to allocate @newlines in one swell foop).
Re: Find and Replace with special characters
by Anonymous Monk on May 07, 2015 at 00:51 UTC
    as the substitution operator requires regex, if you want simple string substitution , you need to use quotemeta
Re: Find and Replace with special characters
by Anonymous Monk on May 07, 2015 at 07:54 UTC

    # XXX this modifies the input @lines ! my ($from, $to) = ( '#<-(0N<-(s3T' => '*<-(0N<-(s3T' ); for (@lines) { s/\Q$from\E/$to/g; } my @newlines = @lines; # XXX this modifies the input @lines ! for (@lines) { s{\Q#<-(0N<-(s3T\E}{*<-(0N<-(s3T}g; } my @newlines = @lines; # don't modify @input, copy it my @newlines = @lines; for (@newlines) { s{\Q#<-(0N<-(s3T\E}{*<-(0N<-(s3T}g; } # or, work on a copied my($var) my @newlines; for (@lines) { my $str = $_; $str =~ s{\Q#<-(0N<-(s3T\E}{*<-(0N<-(s3T}g; push @newlines, $str; } # or, use non-destructive s///r my @newlines; for (@lines) { push @newlines, s{\Q#<-(0N<-(s3T\E}{*<-(0N<-(s3T}gr; } # and again, more concise using a map: my @newlines = map s{\Q#<-(0N<-(s3T\E}{*<-(0N<-(s3T}gr, @lines;

Re: Find and Replace with special characters
by edimusrex (Monk) on May 07, 2015 at 15:15 UTC
    There are a lot of special regex characters in your string which need to be escaped to be properly matched.

    Something like this is probably what you are looking for

    foreach(@lines) { if (s/^\#\<\-\(0N\<\-\(s3T$/*<-(0N<-(s3T/g) { push @newlines, $_; } }


    Adding the ^ (beginning of the line anchor) and $ (end of the line anchor) is important so you don't get any partial matches