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

→‎{{header|Lambdatalk}}: adding a better one
(Promoted to 'full' task - plenty of implementations, no controversy.)
(→‎{{header|Lambdatalk}}: adding a better one)
Line 168:
 
=={{header|Lambdatalk}}==
 
1) first answer
 
We first translate the replacements program into a sequence of rules
<pre>
the first 'a' with 'A' -> aA1
...and so on
</pre>
 
Then we add to the existing set of array functions a new one finding the indexes of some value in a given array.
<lang Scheme>
{def A.findindexes
1) Using regular expressions
 
{def A.findindexes.rec
{lambda {:v :a :b :i}
{if {A.empty? :a}
then :b
else {A.findindexes.rec :v {A.rest :a}
{if {W.equal? {A.first :a} :v}
then {A.addlast! :i :b}
else :b}
{+ :i 1}} }}}
 
{lambda {:v :a}
{A.findindexes.rec :v :a {A.new} 0} }}
-> A.findindexes
{A.findindexes a {A.split abracadabra}}
-> [0,3,5,7,10]
... and so on
</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.
 
<lang Scheme>
{def replacements.rules
{lambda {:w :r}
{A.new
{W.get 0 :r}
{W.get 1 :r}
{A.get {- {W.get 2 :r} 1} // arrays begin at 0
{A.findindexes {W.get 0 :r} {A.split :w}}}}}}
-> replacements.rules
 
{A.join {replacements.rules abracadabra aA1}}
-> aA0
... and so on
</lang>
 
Finally the replacements function will apply this sequence of rules to the word.
 
<lang Scheme>
{def replacements
 
{def replacements.rec
{lambda {:word :rules}
{if {A.empty? :rules}
then {A.join :word}
else {replacements.rec {A.set! {A.get 2 {A.first :rules}}
{A.get 1 {A.first :rules}}
:word}
{A.rest :rules}} }}}
 
{lambda {:word :rules}
{replacements.rec
{A.split :word}
{A.map {replacements.rules :word} {A.new :rules}} }}}
-> replacements
 
{replacements abracadabra aA1 aB2 aC4 aD5 bE1 rF2}
-> AErBcadCbFD
(AErBcadCbFD)
 
{replacements caaarrbabad aA1 aB2 aC4 aD5 bE1 rF2}
-> cABarFECbDd
(cABarFECbDd)
</lang>
 
2) second answer using regexps
 
Here is a quick & dirty answer using the S.replace_once primitive.
 
<lang Scheme>
{def multrepl_rex
{lambda {:word :rules}
Line 176 ⟶ 256:
then :word
else {multrepl_rex
{S.replace_onereplace_once {W.first {A.first :rules}}
by {W.last {A.first :rules}}
in :word }
Line 193 ⟶ 273:
(AErBcadCbFD)
</lang>
 
2) For a more general (and more complex) algorithm see http://lambdaway.free.fr/lambdawalks/?view=replace
 
=={{header|Phix}}==