Your specific problem (things being printed in the wrong order) appears to be due to the combination of double quotes and the x modifier. The double quotes in my $searchPattern = "(^\#!/usr/bin/perl.*?\n)"; causes "\#" to be inserted in the string as plain "#". The x modifier causes Perl to read "#" as the start of a comment. Thus the regex ends up being ^ alone followed by a comment whose text is "!/usr/bin/perl". The net effect is that $1 evaluates to the empty string. The regular expression matches the position at the start of the string and so inserts $insertion at the start of the string. /usr/bin/perl is never matched.
Now for how to avoid such problems in the future:
- use strictures. That is, start your script with use strict; use warnings;. Had you done so you would have noticed a problem right away.
In addition to the bareword in use English... (which should be use English qw(no_match_vars)), you would have seen the message alerting you to a problem in the regular expression: Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE ^#!/usr/bin/perl[^\n]*\n)/.
- use \\ in double quoted strings when you want to insert an actual backslash rather than just escape the next character.
- use test strings with data before and after the insertion point, e.g. "#!/usr/bin/perl \n\n\nyaba-dubba-doo\n";. Had you done that it would have been more obvious that it wasn't "reversing the order" but rather it was matching the start of the string alone.
And a few comments on best practice:
- avoid .*? and .* They rarely do what you want. A better choice is something more specialized like [^\n]*\n. This specifically allows one to skip past all characters on the same line and stops at the end of the line.
- avoid using '?' as a separator in substitutions (the s/// operator). At best it is confusing. '?' has a special meaning within regular expressions. Also ?pattern? "once only" searches are "vaguely deprecated". In the future you might want to consider something like s||| or s{}{}. The later can be used even with variables expressed as ${varname}. Perl knows how to handle nesting properly. See perlop for details.
- Avoid slurping except in one liners. Get in the habit of using while ($line=<INFILE>) {...} instead. It uses far less memory.
- When printing out variables use non-whitespace to surround the variable value so that you can easily see unexpected hidden whitespace. print "content=<$content>\n" is far more likely to alert you to problems that
print "content=\n$content\n"
The following code illustrates these points and outputs the insertion code in the correct position:
#!/usr/bin/perl -w ###-DDEBUGGING -d -Dslt`
use strict;
use warnings;
use Env;
use English qw( no_match_vars );
my $searchPattern='(^\#!/usr/bin/perl[^\n]*\n)';
my $insertion = "\nuse English \( no_match_vars \);\n";
my $content = "#!/usr/bin/perl \n\nyaba-dubba-doo\n";
print "content = <$content>\n";
print "insertion = <$insertion>\n";
$content =~ s?$searchPattern?${1}${insertion}?msx;
print "content now = <$content>";
exit 0;
which outputs
content = <#!/usr/bin/perl
yaba-dubba-doo
>
insertion = <
use English ( no_match_vars );
>
content now =<#!/usr/bin/perl
use English ( no_match_vars );
yaba-dubba-doo
>
Best, beth
Updated: explain specific cause of error and added code sample.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.