Your skill will accomplishwhat the force of many cannot PerlMonks

### Replacing a specfied instance of a pattern in a string

by krisahoch (Deacon)
 on Jul 14, 2005 at 21:22 UTC Need Help??

krisahoch has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I have an interesting problem where I need to replace a specific instance of a word in a string.

Example String:Fsih my test variable is fsihd or is it gfsih or gfsihd fsih

I may want to replace the third instance of 'fsih' with 'fish', or the fourth, or even the last. How would you do that? I have tried several ways (regexp) but I failed each time.

Kristofer

• Comment on Replacing a specfied instance of a pattern in a string

Replies are listed 'Best First'.
Re: Replacing a specfied instance of a pattern in a string
by ikegami (Patriarch) on Jul 14, 2005 at 21:32 UTC
```my \$str      = 'Fsih my test variable is fsihd or is it gfsih or gfsih
+d fsih';
#                                        1111            2222     3333
+  4444
my \$substr   = 'fsih';
my \$replace  = 'fish';
my \$instance = 3;  # 3rd

print("\$str\n");

my \$pos = -length(\$substr);

for (;;) {
last if !\$instance--;
\$pos = index(\$str, \$substr, \$pos + length(\$substr));
last if \$pos < 0;
}

substr(\$str, \$pos, length(\$substr), \$replace)
if \$pos >= 0;

print("\$str\n");

Update: Fixed off-by-one error.

A tad simpler looping, and case-insensitive:
```my \$foo   = 'Fsih my test variable is fsihd or is it gfsih or gfsihd f
+sih';
my \$from  = 'fsih';
my \$which = 3;
my \$to    = 'FISH'; # makes it easy to see

\$foo =~ /\Q\$from\E/ig for (1..\$which);
substr(\$foo, pos(\$foo) - length(\$from), length(\$from), \$to) if pos(\$fo
+o);
print "Foo = \$foo\n";

Caution: Contents may have been coded under pressure.
That reminds me of /c!
```my \$str      = 'Fsih my test variable is fsihd or is it gfsih or gfsih
+d fsih';
#                                        1111            2222     3333
+  4444
my \$substr   = 'fsih';
my \$regexp   = qr/\Q\$substr\E/;
my \$replace  = 'fish';
my \$instance = 3;  # 3rd

print("\$str\n");

scalar \$str =~ /\G.*?\$regexp/gc
while --\$instance;

\$str =~ s/\G(.*?)\$regexp/\$1\$replace/;

print("\$str\n");

The /c is needed in case there are less than \$instance instances of the search string.

Now, is there a way to do it with Regular Expression?
```my \$str      = 'Fsih my test variable is fsihd or is it gfsih or gfsih
+d fsih';
#                                        1111            2222     3333
+  4444
my \$substr   = 'fsih';
my \$regexp   = qr/\Q\$substr\E/;
my \$replace  = 'fish';
my \$instance = 3;  # 3rd

print("\$str\n");

my \$pre_count = \$instance - 1;
\$str =~ s/((?:\$regexp.*?){\$pre_count})\$regexp/\$1\$replace/;

print("\$str\n");

You might have noticed both of these are case sensitive. Both can be made case-insensitive. The non-regexp version is most likely much faster. The regexp version can handle regexps instead of constant strings.

Re: Replacing a specfied instance of a pattern in a string
by Roy Johnson (Monsignor) on Jul 14, 2005 at 21:40 UTC
One way:
```my \$foo = 'Fsih my test variable is fsihd or is it gfsih or gfsihd fsi
+h';
# Replace the 3rd
print "Foo = \$foo\n";

Caution: Contents may have been coded under pressure.

or to pass the index in use:

```use warnings;
use strict;

my \$foo = 'Fsih my test variable is fsihd or is it gfsih or gfsihd fsi
+h';
my \$i = 2; # Replace the 3rd
print "Foo = \$foo\n";

Perl is Huffman encoded by design.
Re: Replacing a specfied instance of a pattern in a string (2 more)
by tye (Sage) on Jul 15, 2005 at 05:17 UTC
```my \$i= 0;
\$str =~ s/(...)/ 3 == ++\$i ? 'fish' : \$1 /ge;
or
```my \$i = 3;
0 while \$str =~ /fsih/gi && --\$i;
substr( \$str, \$-[0], \$+[0]-\$-[0], 'fish' )   if  ! \$i;

- tye

Re: Replacing a specfied instance of a pattern in a string
by Jasper (Chaplain) on Jul 15, 2005 at 11:01 UTC
```my \$instance = 3;
\$string = s/fsih/--\$instance?\$&:'fish'/eg;

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://475052]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2022-07-04 06:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?