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

Hi Monks

I have a variable which contains perl coding.

$a=' $text=~s#Find \#Text#Replace Text#; $text=~s/Find \/Text/Replace Text/; $text=~s{Find \}Text}{Replace Text}; ';
I need to get find patter and replace patter into variabls from $text variable.
if ($a=~m#$text=~s(.)\s*(?<!\1)#) { # need value $findtext='Find \#Text'; # need value $repltext='Replace Text'; }

when I ran this, It will showing an error message.

Variable length lookbehind not implemented in regex; marked by <-- HER +E in m/=~\s*s(.)(?<!\1) <-- HERE / at script.pl line 8 (#1) (F) Lookbehind is allowed only for subexpressions whose length is +fixed and known at compile time. The <-- HERE shows in the regular expressio +n about where the problem was discovered. See perlre. Uncaught exception from user code: Variable length lookbehind not implemented in regex; marked by + <-- HERE in m/=~\s*s(.)(?<!\1) <-- HERE / at script.pl line 8.

Please guide me how can i do this.

Thanks
Kanishk

Replies are listed 'Best First'.
Re: Regexp help!!
by inman (Curate) on Oct 21, 2005 at 11:30 UTC
    I have commented a regex that works with the data that you have provided. The two values that you are looking for are placed in $2 and $3.
    use strict; use warnings; my $a=' $text=~s#Find \#Text#Replace Text#; $text=~s/Find \/Text/Replace Text/; $text=~s{Find \}Text}{Replace Text}; '; if ($a =~ / # start \$text=~s # remember to escape the $ to avoid interpolation (.) # capture the '#' (.*?) # match any non-newline character non-greedily (?<!\\) # make sure the '#' is not escaped in your data \1 # the first unescaped '#' (.*?) # match any non-newline character non-greedily \1; # the second '#' /x # end ) { # need value $findtext='Find \#Text'; print "$2\n"; # need value $repltext='Replace Text'; print "$3\n" }
      You might have a problem with an escaped backslash before the 2nd #. Your (.*?) should probably be
      ((?:\\?.)*?) # match possibly-backslashed non-newline, non-greedy

      Caution: Contents may have been coded under pressure.
Re: Regexp help!!
by Samy_rio (Vicar) on Oct 21, 2005 at 11:28 UTC

    Hi Kanish, Try to use Negative Look ahead (?!).

    if ($a=~m#$text=~s(.)\s*(?<!\1)#) should be if ($a=~m#$text=~s(.)\s*(?!\1)#)

    Regards,
    Velusamy R.

Re: Regexp help!!
by Util (Priest) on Oct 22, 2005 at 01:32 UTC

    PPI can do most of the work for you. The code below illustrates how to use PPI to extract the find and replace patterns.

    Note: The current PPI, version 1.103, has a bug that I have worked around in my code. I am submitting a patch to fix the bug; when a version is released without the bug, I will post an update with the new version number.

    Working, tested code:

    use strict; use warnings; use PPI; my $source_code = <<'END_OF_SOURCE_CODE'; $text =~ s#Find \#Text#Replace Text#; $text =~ s/Find \/Text/Replace Text/; $text =~ s{Find \}Text}{Replace Text}; $text =~ s{Find \}Text} {Replace Text}; $text =~ s[(Find) (\}Text)] <Replace Text>io; END_OF_SOURCE_CODE my $Document = PPI::Document->new(\$source_code) or die; my $subs = $Document->find('PPI::Token::Regexp::Substitute'); #use Data::Dumper; $Data::Dumper::Useqq = 1; #print Dumper $subs; #exit; foreach ( @{ $subs } ) { my $type = $_->{'braced'} ? 'Braced' : 'Not Braced'; my ( $find_text, $repl_text ) = extract_subst_strings($_); print "\n$type\n"; print "find_text = '$find_text'\n"; print "repl_text = '$repl_text'\n"; } # Fails on braced substitute statements in PPI 1.103 #sub extract_subst_strings { # my %s = %{ $_[0] }; # # return map { # substr( $s{'content'}, $_->{'position'}, $_->{'size'} ) # } @{ $s{'sections'} }; #} sub extract_subst_strings { my ($substitute_statement) = @_; my %s = %$substitute_statement; warn unless $s{'_sections'} == 2; warn unless @{ $s{ 'sections'} } == 2; my $content = $s{'content' }; my @sections = @{ $s{'sections'} }; my ( $find_text, $repl_text ); if ( $s{'braced'} ) { $find_text = substr( $content, $sections[0]{'position'}, $sections[0]{'size'}, ); $repl_text = substr( $content, $sections[1]{'position'} - $sections[1]{'size'} - 1, $sections[1]{'size'}, ); } else { ( $find_text, $repl_text ) = map { substr( $content, $_->{'position'}, $_->{'size'} ) } @sections; } return ( $find_text, $repl_text ); }

Re: Regexp help!!
by ambrus (Abbot) on Oct 21, 2005 at 15:15 UTC