$string =~ s!\n/\n/!!
Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring! | [reply] [d/l] |
The following program reads in a file, and if it finds a line that
starts with GRANT, followed by a line containing whatever, followed
by two lines containing just a '/', it will remove the slashes from
the latter two lines. This is how I interpret what you want; however,
your specification isn't very exact.
use strict;
use warnings;
my @buffer;
for (1 .. 4) {
push @buffer => scalar <>;
last unless defined $buffer [-1];
}
while (defined $buffer [-1]) {
if ($buffer [0] =~ /^GRANT/ && $buffer [2] eq "/\n"
&& $buffer [3] eq "/\n") {
$buffer [2] = $buffer [3] = "\n";
}
print shift @buffer;
push @buffer => scalar <>;
}
pop @buffer;
print @buffer;
__END__
Abigail
| [reply] [d/l] |
$str =~ s#/## for 1,2;
or
s#(/\s*){2}\z##
for example. But these assume you slurp the entire file into a string. Perhaps you are doing a perl -pe kind of thing...
perl -i.old -pe '$sawSlash++ && s#/## if m#/#'
(updated again. Thanks, blakem. I added "$str =~" to match what I was thinking and what I had tested.)
- tye (sààaaaà x y z aziez,s $e $s deedeydi,t $ex,print)
| [reply] [d/l] [select] |
s#/## for 1,2;
That won't work. $_ gets aliased in the for loop to the constants '1' and '2'. You could get away with:
for my $i (1,2) { s#/## }
Though, its not real pretty...
-Blake
| [reply] [d/l] [select] |
Oh well, if everybody's joining in:
s|/{2,}|/|;
which will remove an unlimited number of extra slashes.
And if you've got multiline strings: s|(?:/\n){2,}|/\n|;
--
Tommy
Too stupid to live.
Too stubborn to die.
| [reply] [d/l] [select] |
you can always read the next line after your long line by:
$line = <FILE>; ### this will give you the first / that you want to
+preserve
and remove any / after it using the regexp you mentioned
Hotshot | [reply] [d/l] |
Another way, expressing the logic, that the first / mustn't removed, but all others is to say it explizitly.
Assuming the sql statement is one line $sql:
1 while $sql =~ s%(/.*)/%$1%gs;
or with the futuring keep syntax:
use Regexp::Keep; # I believe, it will be unnecessary on Perl 5.10
1 while $sql =~ s%/.*\K/%%gs;
Greetings,
Janek | [reply] [d/l] [select] |
Something which I believe may be of some interest to you is the \G zero width assertion.
$_ = "1/ 2/ 3/";
m{/}g; # will set pos to 2, the offset of the first '/'
s{\G(.*?)/}{$1}g; # \G is like ^, but instead of matching
# a line begining it matches the place
# where the last /g modified regexp left
# off.
print;
The above code first finds a slash, and saves it's position in the lvalue acccessible by pos($_). Because the m//g is not performed in list context, the slashes are not all pushed to a list and returned. Scalar/void context m//g lets you step through the string, in an iterational fashion.
Next, the substitution is performed so that the match has to succeed \G. \G is the place where the last /g left off. /g modification on s/// substitutes everything regardless of context. The first slash found, and it's position noted, we proceed to find a minimal anything, followed by a slash. Once we find that, we replace it with the minimal anything, and remember the position. We then search onward for more slashes, until no match can be made.
This specific example is a bit flawed, because it invloves a lot of copying, in theory, and it is also not the best choice for your specific example, but I just thought it may be useful to know.
perlre contains more info.
-nuffin zz zZ Z Z #!perl | [reply] [d/l] |