What is the regular Expression to uncomment a block of Perl code in Eclipse?
I need a regular expression to uncomment a block of Perl code, commented with #
in each line.
As of now, my find expression in the Eclipse IDE is (^#(.*$\R)+)
which matches the commented block, but if I give $2
as the replace expression, it only prints the last matched line. How do I remove the #
while replacing?
For example, I need to convert:
# print "yes";
# print "no";
# print "blah开发者_StackOverflow";
to
print "yes";
print "no";
print "blah";
In most flavors, when a capturing group is repeated, only the last capture is kept. Your original pattern uses +
repetition to match multiple lines of comments, but group 2 can only keep what was captured in the last match from the last line. This is the source of your problem.
To fix this, you can remove the outer repetition, so you match and replace one line at a time. Perhaps the simplest pattern to do this is to match:
^#\s*
And replace with the empty string.
Since this performs match and replacement one line at a time, you must repeat it as many times as necessary (in some flavors, you can use the g
global flag, in e.g. Java there are replaceFirst/All
pair of methods instead).
References
- regular-expressions.info/Repeating a Captured Group vs Capturing a Repeated Group
Related questions
- Is there a regex flavor that allows me to count the number of repetitions matched by
*
and+
?- .NET regex keeps all repeated matches
Special note on Eclipse keyboard shortcuts
It Java mode, Eclipse already has keyboard shortcuts to add/remove/toggle block comments. By default, Ctrl
+/
binds to the "Toggle comment" action. You can highlight multiple lines, and hit Ctrl
+/
to toggle block comments (i.e. //
) on and off.
You can hit Ctrl
+Shift
+L
to see a list of all keyboard shortcuts. There may be one in Perl mode to toggle Perl block comments #
.
Related questions
- What is your favorite hot-key in Eclipse?
- Hidden features of Eclipse
Search with ^#(.*$)
and replace with $1
You can try this one: -
use strict;
use warning;
my $data = "#Hello#stack\n#overflow\n";
$data =~ s/^?#//g ;
OUTPUT:-
Hello
stack
overflow
Or
open(IN, '<', "test.pl") or die $!;
read(IN, my $data, -s "test.pl"); #reading a file
$data =~ s/^?#//g ;
open(OUT, '>', "test1.pl") or die $!;
print OUT $data; #Writing a file
close OUT;
close IN;
Note: Take care of #!/usr/bin/perl
in the Perl script, it will uncomment it also.
You need the GLOBAL g
switch.
s/^#(.+)/$1/g
In order to determine whether a perl '#' is a comment or something else, you have to compile the perl and build a parse tree, because of Schwartz's Snippet
whatever / 25 ; # / ; die "this dies!";
Whether that '#' is a comment or part of a regex depends on whether whatever() is nullary, which depends on the parse tree.
For the simple cases, however, yours is failing because (^#(.*$\R)+) repeats a capturing group, which is not what you wanted.
But anyway, if you want to handle simple cases, I don't even like the regex that everyone else is using, because it fails if there is whitespace before the # on the line. What about
^\s*#(.*)$
? This will match any line that begins with a comment (optionally with whitespace, e.g., for indented blocks).
Try this regex:
(^[\t ]+)(\#)(.*)
With this replacement:
$1$3
Group 1 is (^[\t ]+) and matches all leading whitespace (spaces and tabs).
Group 2 is (#) and matches one # character.
Group 3 is (.*) and matches the rest of the line.
精彩评论