Selectively replace multiple instances of a character within a string: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(28 intermediate revisions by 20 users not shown)
Line 21:
{{Template:Strings}}
<br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V rep = [‘a’ = [1 = ‘A’, 2 = ‘B’, 4 = ‘C’, 5 = ‘D’], ‘b’ = [1 = ‘E’], ‘r’ = [2 = ‘F’]]
 
F trstring(oldstring, repdict)
DefaultDict[Char, Int] seen
V newchars = ‘’
L(c) oldstring
V i = ++seen[c]
newchars ‘’= I c C repdict & i C repdict[c] {repdict[c][i]} E c
R newchars
 
print(‘abracadabra -> ’trstring(‘abracadabra’, rep))</syntaxhighlight>
 
{{out}}
<pre>
abracadabra -> AErBcadCbFD
</pre>
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">CO in the string "abracadabra", replace the first 'a' with 'A', the second 'a' with 'B'
, the fourth 'a' with 'C', the fifth 'a' with 'D'
the first 'b' with 'E', the second 'r' with 'F'
CO
BEGIN
[,]STRING replacements = ( ( "a", "ABaCD" ), ( "b", "E" ), ( "r", "rF" ) );
[ 1 LWB replacements : 1 UPB replacements ]INT position;
STRING input = "abracadabra";
[ LWB input : UPB input ]CHAR output;
FOR i FROM LWB position TO UPB position DO position[ i ] := LWB replacements[ i, 2 ] OD;
FOR c pos FROM LWB input TO UPB input DO
CHAR c = input[ c pos ];
output[ c pos ] := c;
BOOL found := FALSE;
FOR r pos FROM 1 LWB replacements TO 1 UPB replacements WHILE NOT found DO
STRING r = replacements[ r pos, 1 ];
IF c = r[ LWB r ] THEN
found := TRUE;
IF position[ r pos ] <= UPB replacements[ r pos, 2 ] THEN
output[ c pos ] := replacements[ r pos, 2 ][ position[ r pos ] ];
position[ r pos ] +:= 1;
found := TRUE
FI
FI
OD
OD;
print( ( """", input, """ -> """, output, """" ) );
IF output /= "AErBcadCbFD" THEN print( ( " ** UNEXPECTED RESULT" ) ) FI;
print( ( newline ) )
END</syntaxhighlight>
{{out}}
<pre>
"abracadabra" -> "AErBcadCbFD"
</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">replacement: function [rule,ch,order][
loop rule 'r ->
if r\[0] = order -> return r\[1]
return ch
]
multiReplace: function [str, rules][
cntr: #.raw flatten couple keys rules repeat 0 size rules
 
join map str 'ch [
(key? cntr ch)? [
cntr\[ch]: cntr\[ch] + 1
replacement rules\[ch] ch dec cntr\[ch]
] -> ch
]
]
 
print multiReplace "abracadabra" #[
a: [[0 `A`][1 `B`][3 `C`][4 `D`]]
b: [[0 `E`]]
r: [[1 `F`]]
]</syntaxhighlight>
 
{{out}}
 
<pre>AErBcadCbFD</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">str := "abracadabra"
steps := [[1, "a", "A"]
, [2, "a", "B"]
, [4, "a", "C"]
, [5, "a", "D"]
, [1, "b", "E"]
, [2, "r", "F"]]
 
MsgBox % result := Selectively_replace(str, steps)
return
 
Selectively_replace(str, steps){
Res := [], x := StrSplit(str)
for i, step in steps {
n := step.1, L := step.2, R := step.3, k := 0
for j, v in x
if (v=L) && (++k = n) {
Res[j] := R
break
}
}
for j, v in x
result .= Res[j] = "" ? x[j] : Res[j]
return result
}</syntaxhighlight>
{{out}}
<pre>AErBcadCbFD</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(void) {
const char string[] = "abracadabra";
 
char *replaced = malloc(sizeof(string));
strcpy(replaced, string);
 
// Null terminated replacement character arrays
const char *aRep = "ABaCD";
const char *bRep = "E";
const char *rRep = "rF";
 
for (char *c = replaced; *c; ++c) {
switch (*c) {
case 'a':
if (*aRep)
*c = *aRep++;
break;
case 'b':
if (*bRep)
*c = *bRep++;
break;
case 'r':
if (*rRep)
*c = *rRep++;
break;
}
}
 
printf("%s\n", replaced);
 
free(replaced);
return 0;
}
</syntaxhighlight>
{{out}}
<pre>
AErBcadCbFD
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <map>
#include <iostream>
#include <string>
Line 46 ⟶ 203:
 
std::cout << magic << "\n";
}</langsyntaxhighlight>
{{out}}
<pre>
AErBcadCbFD
</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
var TestStr: string = 'abracadabra';
 
 
function FindNthChar(C: char; S: string; N: integer): integer;
{Routine to find the Nth version of C, string S}
begin
for Result:=1 to Length(S) do
if S[Result]=C then
begin
Dec(N);
if N<=0 then exit;
end;
Result:=-1;
end;
 
 
procedure ReplaceNthChar(COld,CNew: char; var S: string; N: integer);
{Find and replace the Nth version COld with CNew}
var Inx: integer;
begin
Inx:=FindNthChar(COld,S,N);
if Inx<1 then exit;
S[Inx]:=CNew;
end;
 
 
procedure SelectivelyReplaceChars(Memo: TMemo);
var I: integer;
begin
Memo.Lines.Add('Before: '+TestStr);
{Do the replacement toward the end of string first}
ReplaceNthChar('a','D',TestStr,5);
ReplaceNthChar('a','C',TestStr,4);
ReplaceNthChar('a','B',TestStr,2);
ReplaceNthChar('r','F',TestStr,2);
ReplaceNthChar('a','A',TestStr,1);
ReplaceNthChar('b','E',TestStr,1);
Memo.Lines.Add('After: '+TestStr);
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
Before: AErBcadCbFD
After: AErBcAdCEFD
Elapsed Time: 1.749 ms.
 
</pre>
 
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
fun transmogrify = text by text input, Map replacements
Map indexes = text%int[]
text result = ""
for each text ch in input
result.append(when(replacements.has(++indexes[ch] + ch), replacements[indexes[ch] + ch], ch))
end
return result
end
writeLine(transmogrify("abracadabra",
text%text["1a" => "A", "2a" => "B", "4a" => "C", "5a" => "D", "1b" => "E", "2r" => "F"]))
</syntaxhighlight>
{{out}}
<pre>
Line 54 ⟶ 286:
=={{header|Factor}}==
{{works with|Factor|0.99 2022-04-03}}
<langsyntaxhighlight lang="factor">USING: assocs formatting grouping kernel random sequences ;
 
CONSTANT: instrs {
Line 76 ⟶ 308:
 
"abracadabra" test
"abracadabra" randomize test</langsyntaxhighlight>
{{out}}
<pre>
Line 84 ⟶ 316:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">Function replaceChar(Byref S As String) As String
Dim As String A = "ABaCD", B = "Eb", R = "rF"
Dim As Byte pA = 1, pB = 1, pR = 1
Line 108 ⟶ 340:
S = "caarabadrab"
Print S; " -> "; replaceChar(S)
Sleep</langsyntaxhighlight>
{{out}}
<pre>abracadabra -> AErBcadCbFD
caaarrbabad -> cABarFECbDd</pre>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
void local fn DoIt
long a = 0, b = 0, r = 0, length, i
CFMutableStringRef string = fn MutableStringWithString( @"abracadabra" )
CFStringRef s
length = len(string)
for i = 0 to length - 1
s = NULL
select ( mid(string,i,1) )
case @"a"
a++
select ( a )
case 1 : s = @"A"
case 2 : s = @"B"
case 4 : s = @"C"
case 5 : s = @"D"
end select
case @"b"
b++
if ( b == 1 ) then s = @"E"
case @"r"
r++
if ( r == 2 ) then s = @"F"
end select
if ( s ) then mid(string,i,1) = s
next
NSLog(@"%@",string)
end fn
 
fn DoIt
 
HandleEvents
</syntaxhighlight>
 
{{out}}
<pre>
AErBcadCbFD
</pre>
 
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 140 ⟶ 416:
s = strings.Replace(s, "F", "r", 1)
fmt.Println(s)
}</langsyntaxhighlight>
 
{{out}}
Line 149 ⟶ 425:
=={{header|Haskell}}==
As a map-accumulation:
<langsyntaxhighlight lang="haskell">import Data.List (mapAccumL)
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)
Line 156 ⟶ 432:
 
nthCharsReplaced :: M.Map Char [Maybe Char] -> String -> String
nthCharsReplaced ruleMap = snd . mapAccumL go M.emptyruleMap
where
go a c =
|case M.memberlookup c ruleMapa =of
Nothing let i = fromMaybe 0-> (M.lookupa, c a)
Just [] in-> ( M.inserta, c (succ i) a,
Just (d : ds) ->
otherChar i c (fromMaybe [] (M.lookup c ruleMap))
( M.insert c ds )a,
| otherwise = (a, fromMaybe c) d
)
 
otherChar :: Int -> Char -> [Maybe Char] -> Char
otherChar i c deltas
| i < length deltas = fromMaybe c (deltas !! i)
| otherwise = c
 
--------------------------- TEST -------------------------
Line 181 ⟶ 453:
('b', [Just 'E']),
('r', [Nothing, Just 'F'])
]</langsyntaxhighlight>
{{Out}}
<pre>AErBcadCbFD</pre>
Line 187 ⟶ 459:
=={{header|J}}==
 
<langsyntaxhighlight Jlang="j"> upd=: {{ x (n{I.y=m)} y }}
'ABCD' 'a' upd 0 1 3 4 'E' 'b' upd 0 'F' 'r' upd 1 'abracadabra'
AErBcadCbFD</langsyntaxhighlight>
 
<tt>upd</tt> here takes four arguments -- two on the left (replacement characters, original character) and two on the right(index values for which instances to replace, and the original string).
Line 195 ⟶ 467:
However, here's a more compact approach (the first item in the left argument is the target, and the rest of the left argument explicitly provides values for every instance of that item in the right argument):
 
<langsyntaxhighlight Jlang="j"> chg=: {{ (}.x) (I.y={.x)} y}}
'aABaCD' chg 'bEb' chg 'rrF' chg 'abracadabra'
AErBcadCbFD</langsyntaxhighlight>
 
 
=={{header|Java}}==
{{trans|JavaScript}}
Here's an example translated from JavaScript.
<syntaxhighlight lang="java">
int findNth(String s, char c, int n) {
if (n == 1) return s.indexOf(c);
return s.indexOf(c, findNth(s, c, n - 1) + 1);
}
 
String selectiveReplace(String s, Set... ops) {
char[] chars = s.toCharArray();
for (Set set : ops)
chars[findNth(s, set.old, set.n)] = set.rep;
return new String(chars);
}
 
record Set(int n, char old, char rep) { }
</syntaxhighlight>
<syntaxhighlight lang="java">
selectiveReplace("abracadabra",
new Set(1, 'a', 'A'),
new Set(2, 'a', 'B'),
new Set(4, 'a', 'C'),
new Set(5, 'a', 'D'),
new Set(1, 'b', 'E'),
new Set(2, 'r', 'F'));
</syntaxhighlight>
{{out}}
<pre>AErBcadCbFD</pre>
 
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">function findNth(s, c, n) {
if (n === 1) return s.indexOf(c);
return s.indexOf(c, findNth(s, c, n - 1) + 1);
Line 222 ⟶ 526:
[2, "r", "F"], // the second 'r' with 'F'
])
);</langsyntaxhighlight>
{{out}}
<pre>AErBcadCbFD</pre>
Line 228 ⟶ 532:
 
Or, expressed as a map-accumulation:
<langsyntaxhighlight lang="javascript">(() => {
"use strict";
 
Line 238 ⟶ 542:
// the nth instances of various characters.
s => mapAccumL(
(a, c) => c in ruleMapa ? (() => {
const ds = a[c];
i = a[c] || 0,
ds = ruleMap[c];
 
return Boolean(ds.length) ? [
Object.assign(a, {[c]: ds.slice(1 + i)}),
i < ds.length[0] ?|| (c
] : ds[i] ||a, c];
) : c
];
})() : [a, c]
)(Object.assign({}, ruleMap)([...s])[1].join("");
[...s]
)[1].join("");
 
 
// ---------------------- TEST -----------------------
const main = () =>
// Instance-specific character replacement rules.
nthInstanceReplaced({
a: ["A", "B", null, "C", "D"],
Line 293 ⟶ 595:
// MAIN --
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>AErBcadCbFD</pre>
 
=={{header|jq}}==
In this section, array-indexing and occurrence-counting are both 0-based except for the transcription of the task in `steps`.
 
'''Generic functions'''
<syntaxhighlight lang="jq">
# Emit empty if the stream does not have an $n-th item
# Note: jq's nth/2 does not serve our purposes.
def n_th($n; stream):
if $n < 0 then empty
else foreach stream as $x (-1; .+1; if . == $n then $x else empty end)
end;
 
def positions(stream; $v):
foreach stream as $x (-1; .+1; if $v == $x then . else empty end);
 
# Input: an array or string.
# Output: the input with an occurrence of $old replaced by $new.
# . and $reference are assumed to be of the same type and length.
# The search occurs in $reference and the corresponding spot in . is modified.
def replace_nth($occurrence; $old; $new; $reference):
if type == "array"
then ($reference | n_th($occurrence; positions(.[]; $old)) // null) as $ix
| if $ix then .[:$ix] + [$new] + .[$ix + 1:] else . end
else explode
| replace_nth($occurrence; $old|explode|first; $new|explode|first; $reference|explode)
| implode
end;
</syntaxhighlight>
 
'''The task'''
<syntaxhighlight lang="jq">
def steps:
[1, "a", "A"],
[2, "a", "B"],
[4, "a", "C"],
[5, "a", "D"],
[1, "b", "E"],
[2, "r", "F"];
 
def task(steps):
. as $reference
| reduce steps as [$occurrence, $old, $new] (.;
replace_nth($occurrence - 1; $old; $new; $reference ));
"abracadabra" | task(steps)
</syntaxhighlight>
{{Output}}
<pre>
AErBcadCbFD
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
<lang ruby>
rep = Dict('a' => Dict(1 => 'A', 2 => 'B', 4 => 'C', 5 => 'D'), 'b' => Dict(1 => 'E'), 'r' => Dict(2 => 'F'))
 
Line 312 ⟶ 665:
 
println("abracadabra -> ", trstring("abracadabra", rep))
</langsyntaxhighlight>{{out}}Same as Perl.
 
=={{header|Lambdatalk}}==
Line 325 ⟶ 678:
 
Then we add to the existing set of array functions a new one finding the indexes of some value in a given array.
<syntaxhighlight lang="scheme">
<lang Scheme>
{def A.findindexes
 
Line 345 ⟶ 698:
-> [0,3,5,7,10]
... and so on
</syntaxhighlight>
</lang>
 
Using findindexes we can translate the aA1 aB2 aC4 aD5 bE1 rF2 sequence into a new one where numbers are replaced by indexes in the given string, here abracadabra.
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def replacements.rules
{lambda {:w :r}
Line 362 ⟶ 715:
-> aA0
... and so on
</syntaxhighlight>
</lang>
 
Finally the replacements function will apply this sequence of rules to the word.
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def replacements
 
Line 391 ⟶ 744:
-> cABarFECbDd
(cABarFECbDd)
</syntaxhighlight>
</lang>
 
2) second answer using regexps
Line 397 ⟶ 750:
Here is a quick & dirty answer using the S.replace_once primitive.
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def multrepl_rex
{lambda {:word :rules}
Line 418 ⟶ 771:
-> AErBcadCbFD
(AErBcadCbFD)
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
<syntaxhighlight lang="Nim">import std/tables
 
type
# Table of replacements for a character.
Replacements = Table[int, char]
# Table mapping characters to their replacement table.
ReplacementTable = Table[char, Replacements]
 
const ReplTable = {'a': {1: 'A', 2: 'B', 4: 'C', 5: 'D'}.toTable,
'b': {1: 'E'}.toTable,
'r': {2: 'F'}.toTable
}.toTable
 
proc replace(text: string; replTable: ReplacementTable): string =
var counts: Table[char, int] # Follow count of characters.
for c in text:
if c in replTable:
counts.mgetOrPut(c, 0).inc # Update count for this char.
let pos = counts[c]
result.add replTable[c].getOrDefault(pos, c)
else:
result.add c
 
echo replace("abracadabra", ReplTable)
</syntaxhighlight>
 
{{out}}
<pre>AErBcadCbFD
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
Line 435 ⟶ 819:
 
my $word = 'abracadabra';
say "$word -> " . transmogrify $word, 'a' => 'AB_CD', 'r' => '_F', 'b' => 'E';</langsyntaxhighlight>
{{out}}
<pre>abracadabra -> AErBcadCbFD</pre>
Line 443 ⟶ 827:
=={{header|Phix}}==
Couldn't really decide which I prefer so posted both.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">replace_nth</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
Line 467 ⟶ 851:
<span style="color: #0000FF;">{{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span><span style="color: #008000;">'r'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"F"</span><span style="color: #0000FF;">}}</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">replace_nths</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"abracadabra"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 473 ⟶ 857:
"AErBcadCbFD"
</pre>
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="Phixmonti">/# Rosetta Code problem: https://rosettacode.org/wiki/Selectively_replace_multiple_instances_of_a_character_within_a_string
by Galileo, 11/2022 #/
 
include ..\Utilitys.pmt
 
"ABaCD" var A "Eb" var B "rF" var R
 
"abracadabra" len for >ps
tps get tochar
dup "a" == if drop A pop var A tps set else
dup "b" == if drop B pop var B tps set else
"r" == if R pop var R tps set
endif endif endif
ps> drop
endfor
 
pstack</syntaxhighlight>
{{out}}
<pre>
["AErBcadCbFD"]
 
=== Press any key to exit ===</pre>
 
=={{header|Python}}==
{{trans|Julia}}
<langsyntaxhighlight lang="python">from collections import defaultdict
 
rep = {'a' : {1 : 'A', 2 : 'B', 4 : 'C', 5 : 'D'}, 'b' : {1 : 'E'}, 'r' : {2 : 'F'}}
Line 489 ⟶ 897:
 
print('abracadabra ->', trstring('abracadabra', rep))
</syntaxhighlight>
</lang>
 
===Alternative===
<langsyntaxhighlight lang="python">import functools
 
from typing import Iterable
Line 525 ⟶ 933:
],
)
)</langsyntaxhighlight>
{{out}}
<pre>AErBcadCbFD</pre>
Line 531 ⟶ 939:
 
Or, as a map-accumulation:
<langsyntaxhighlight lang="python">'''Instance-specific character replacement rules'''
 
from functools import reduce
Line 540 ⟶ 948:
def nthInstanceReplaced(ruleMap):
def go(a, c):
ifds c= ina.get(c, ruleMap:None)
return i = a.get(c, 0)
deltas = ruleMap.getdict(a, **{c: ds[1:]}),
returnds[0] (or c
) if ds else dict(a, **{c: 1 + i}),
deltas[i] or c if i < len(deltas) else c
)
else:
return a, c
 
return lambda s: ''.join(
mapAccumL(go)({}ruleMap)(s)[1]
)
 
Line 597 ⟶ 1,001:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>AErBcadCbFD</pre>
 
=={{header|Quackery}}==
 
If there is no nth instance of a particular character in the string, <code>selectivereplace</code> will disregard it. For example, if the nest of replacements in the example included <code>[ 1 char z char ! ]</code> the output would be the same, as there is no z in "abracadabra".
 
<syntaxhighlight lang="Quackery"> [ dup size temp put
witheach
[ over = if
[ swap 1 -
tuck 0 = if
[ i^ temp replace
conclude ] ] ]
2drop
temp take ] is nfind ( n c $ --> n )
 
[ temp put
[] [] rot witheach
[ 2 pluck
dip rot join unrot
nested join ]
[] swap witheach
[ do
temp share nfind
join ]
temp take 0 join unrot
witheach
[ dip [ behead rot ]
poke swap ]
drop
-1 split drop ] is selectivereplace ( [ $ --> $ )
 
 
' [ [ 1 char a char A ]
[ 2 char a char B ]
[ 4 char a char C ]
[ 5 char a char D ]
[ 1 char b char E ]
[ 2 char r char F ] ]
$ "abracadabra"
selectivereplace echo$</syntaxhighlight>
 
{{out}}
 
<pre>AErBcadCbFD</pre>
 
Line 604 ⟶ 1,052:
Set up to not particularly rely on absolute structure of the word. Demonstrate with both the original 'abracadabra' and with a random shuffled instance.
 
<syntaxhighlight lang="raku" perl6line>sub mangle ($str is copy) {
$str.match(:ex, 'a')».from.map: { $str.substr-rw($_, 1) = 'ABaCD'.comb[$++] };
$str.=subst('b', 'E');
Line 613 ⟶ 1,061:
say $_, ' -> ', .&mangle given 'abracadabra';
 
say $_, ' -> ', .&mangle given 'abracadabra'.comb.pick(*).join;</langsyntaxhighlight>
 
{{out}}
Line 619 ⟶ 1,067:
caarabadrab -> cABraECdFDb</pre>
 
=={{header|VlangRPL}}==
The character "-" in the rule string means that no replacement should be made for the occurrence concerned. Any other character can be chosen by modifying the code appropriately.
 
Due to the use of <code>INCR</code> and <code>REPL</code> instructions, this program will only work directly on HP48 compatible RPL versions. HP28 users must have programmed their own version of these instructions.
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ 0 → car rule occ
≪ 1 OVER SIZE '''FOR''' j
'''IF''' DUP j DUP SUB car == '''THEN'''
rule 'occ' INCR DUP SUB
'''IF''' DUP "-" == '''THEN''' DROP '''ELSE''' j SWAP REPL '''END'''
'''END NEXT'''
≫ ≫ ''''REPLR'''' STO
|
'''REPLR''' ''( "string" "character" "rule" -- "string" ) ''
loop for j = 1 to string length
if string[j] == character
get todo = rule[++occ]
replace if todo is different from "-"
end if end loop
return string
|}
{{in}}
<pre>
"abracadabra"
≪ "a" "AB-CD" REPLR "b" "E" REPLR "r" "-F" REPLR ≫ EVAL
</pre>
{{out}}
<pre>
1: "AErBcadCbFD"
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">str = "abracadabra"
rules = [
["a", 1, "A"],
["a", 2, "B"],
["a", 4, "C"],
["a", 5, "D"],
["b", 1, "E"],
["r", 2, "F"]]
 
indices = Hash.new{[]}
str.each_char.with_index{|c, i| indices[c] <<= i}
 
rules.each{|char, i, to| str[indices[char][i-1]] = to}
 
p str</syntaxhighlight>
{{out}}
<pre>"AErBcadCbFD"
</pre>
=={{header|sed}}==
<syntaxhighlight lang="sed">s/a\([^a]*\)a\([^a]*a[^a]*\)a\([^a]*\)a/A\1B\2C\3D/
s/b/E/
s/\(r[^r]*\)r/\1F/</syntaxhighlight>
 
=={{header|V (Vlang)}}==
A similar approach to the C++ entry.
<langsyntaxhighlight lang="ruby">fn selectively_replace_chars(s string, char_map map[string]string) string {
mut bytes := s.bytes()
mut counts := {
Line 648 ⟶ 1,155:
println('$old -> $new')
}
}</langsyntaxhighlight>
 
{{out}}
Line 661 ⟶ 1,168:
{{libheader|Wren-regex}}
Not particularly succinct but, thanks to a recently added library method, better than it would have been :)
<langsyntaxhighlight ecmascriptlang="wren">import "./seq" for Lst
import "./str" for Str
 
Line 672 ⟶ 1,179:
s = Str.replace(s, "b", "E", 1)
s = Str.replace(s, "r", "F", 2, 1)
System.print(s)</langsyntaxhighlight>
 
{{out}}
Line 680 ⟶ 1,187:
 
Alternatively, using regular expressions (embedded script) producing output as before.
<langsyntaxhighlight ecmascriptlang="wren">import "./regex" for Regex
 
var s = "abracadabra"
Line 690 ⟶ 1,197:
s = Regex.compile("b").replace(s, "E")
s = Regex.compile("r").replaceAll(s, "F", 2, 1)
System.print(s)</langsyntaxhighlight>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">string 0;
proc Mangle(S);
char S, A, B, R;
Line 712 ⟶ 1,219:
S:= "caarabadrab";
Text(0, S); Text(0, " -> "); Mangle(S); Text(0, S); CrLf(0);
]</langsyntaxhighlight>
 
{{out}}
9,476

edits