If you use capturing paranthesis in conjunction with a backreference you will be able to keep what matched while still adding to it. In a simple single-line example, this works:
my $text = "Here is some text.";
my $insert = "boring ";
$text =~ s/(some\s)/$1$insert/;
Captures can be a little confusing. Just understand that what matches within parenthesis is captured into $1, $2, etc. You're going to use one set of parens, so when you get a match, $1 contains what matched. That means that s/(pattern)/$1/; is substituting what matched with what matched (ie, not doing much of anything). But when you add the $insert portion after (which can be any scalar, or literal text) you now are matching, keeping what matched, and adding something to it.
But you want to match a string that contains newlines in it. For that, you either need to specify those newlines within the regexp, or use the /s modifier at the end of the match operator so that the s///s operator will treat multiline strings as all one entity (and so that dot and \s match on newlines too).
my $text = "Here is some\nmulti-lined text";
my $insert = "thrilling "
$text =~ s/(some\s)/$1$insert/s;
If you want to continue the same substitution multiple times, also use the /g modifier, like this:
$text =~ s/(some\s)/$1$insert/sg;
If your pattern itself is in multiple lines, that's still ok, it just means that there are newlines embedded in the pattern itself. Still use the /sg modifier, and things will be ok.
my $pattern = "Text with\nnewlines in it";
my $text = ......lots of stuff.....
$text =~ s/(\Q$pattern\E)/$1$insert/sg;
You might find some useful tips in perlretut.
Now in your example you were trying to make use of substr. That's fine. As Zaxo pointed out, substr works quite efficiently if you already know the position at which you wish to insert text. If you use a pattern match to find that position, you use the pos function to determine the position of the match, so that you know where to insert. But if you've gone to the trouble of matching with a regexp, you may as well follow through with a simple s///sg operator rather than a "m//sg", plus a "pos", plus a "substr", all nested within a "while" loop!
Hope this helps!
Dave
"If I had my life to do over again, I'd be a plumber." -- Albert Einstein
|