my $data = <<'END'; foo123bar # foo123bar foo456bar # xyz foo789bar abc foo456bar END $data =~ s{ ^ # beginning of line \h* \# \h* # comment lines \K # keep everything up to here in replacement (? \N*) # capture the comment $ # end of line } { handle_foobar( $+{comment} ) }msxge; sub handle_foobar { return shift =~ s{ foo \K (\d+) (?= bar ) }{ $1 =~ tr/0-9/a-j/r }msxger; } #### my $str = <<'END'; Hello # START World # END Aaa # START Bbb # END Ccc END open my $fh, '<', \$str or die $!; while (<$fh>) { chomp; if ( /^# START/ .. /^# END/ ) { print "<$_>\n"; } } close $fh;