User Tools

A PCRE internal error occured. This might be caused by a faulty plugin

====== Function SUBSTITUTE, SUBSTITUTE-IF, SUBSTITUTE-IF-NOT, NSUBSTITUTE, NSUBSTITUTE-IF, NSUBSTITUTE-IF-NOT ====== ====Syntax==== * **substitute** //newitem// //olditem// //sequence// ''&key'' //from-end// //test// //test-not// //start// //end// //count// //key// → //result-sequence// * **substitute-if** //newitem// //predicate// //sequence// ''&key'' //from-end// //start// //end// //count// //key// → //result-sequence// * **substitute-if-not** //newitem// //predicate// //sequence// ''&key'' //from-end// //start// //end// //count// //key// → //result-sequence// * **nsubstitute** //newitem// //olditem// //sequence// ''&key'' //from-end// //test// //test-not// //start// //end// //count// //key// → //result-sequence// * **nsubstitute-if** //newitem// //predicate// //sequence// ''&key'' //from-end// //start// //end// //count// //key// → //result-sequence// * **nsubstitute-if-not** //newitem// //predicate// //sequence// ''&key'' //from-end// //start// //end// //count// //key// → //result-sequence// ====Arguments and Values==== * //newitem// - an //[[CL:Glossary:object]]//. * //olditem// - an //[[CL:Glossary:object]]//. * //sequence// - a //[[CL:Glossary:proper sequence]]//. * //predicate// - a //[[CL:Glossary:designator]]// for a //[[CL:Glossary:function]]// of one //[[CL:Glossary:argument]]// that returns a //[[CL:Glossary:generalized boolean]]//. * //from-end// - a //[[CL:Glossary:generalized boolean]]//. The default is //[[CL:Glossary:false]]//. * //test// - a //[[CL:Glossary:designator]]// for a //[[CL:Glossary:function]]// of two //[[CL:Glossary:argument|arguments]]// that returns a //[[CL:Glossary:generalized boolean]]//. * //test-not// - a //[[CL:Glossary:designator]]// for a //[[CL:Glossary:function]]// of two //[[CL:Glossary:argument|arguments]]// that returns a //[[CL:Glossary:generalized boolean]]//. * //start//, //end// - //[[CL:Glossary:bounding index designator|bounding index designators]]// of //sequence//. The defaults for //start// and //end// are ''0'' and **[[CL:Constant Variables:nil]]**, respectively. * //count// - an //[[CL:Glossary:integer]]// or **[[CL:Constant Variables:nil]]**. The default is **[[CL:Constant Variables:nil]]**. * //key// - a //[[CL:Glossary:designator]]// for a //[[CL:Glossary:function]]// of one argument, or **[[CL:Constant Variables:nil]]**. * //result-sequence// - a //[[CL:Glossary:sequence]]//. ====Description==== **substitute**, **substitute-if**, and **substitute-if-not** return a copy of //sequence// in which each //[[CL:Glossary:element]]// that //[[CL:Glossary:satisfy the test|satisfies the test]]// has been replaced with //newitem//. **nsubstitute**, **nsubstitute-if**, and **nsubstitute-if-not** are like **substitute**, **substitute-if**, and **substitute-if-not** respectively, but they may modify //sequence//. If //sequence// is a //[[CL:Glossary:vector]]//, the result is a //[[CL:Glossary:vector]]// that has the same //[[CL:Glossary:actual array element type]]// as //sequence//. If //sequence// is a //[[CL:Glossary:list]]//, the result is a //[[CL:Glossary:list]]//. //count//, if supplied, limits the number of elements altered; if more than //count// //[[CL:Glossary:element|elements]]// //[[CL:Glossary:satisfy the test]]//, then of these //[[CL:Glossary:element|elements]]// only the leftmost or rightmost, depending on //from-end//, are replaced, as many as specified by //count//. If //count// is supplied and negative, the behavior is as if zero had been supplied instead. If //count// is **[[CL:Constant Variables:nil]]**, all matching items are affected. Supplying a //from-end// of //[[CL:Glossary:true]]// matters only when the //count// is provided (and //[[CL:Glossary:non-nil]]//); in that case, only the rightmost //count// //[[CL:Glossary:element|elements]]// //[[CL:Glossary:satisfy the test|satisfying the test]]// are removed (instead of the leftmost). //predicate//, //test//, and //test-not// might be called more than once for each //[[CL:Glossary:sequence]]// //[[CL:Glossary:element]]//, and their side effects can happen in any order. The result of all these functions is a //[[CL:Glossary:sequence]]// of the same //[[CL:Glossary:type]]// as //sequence// that has the same elements except that those in the subsequence //[[CL:Glossary:bounded]]// by //start// and //end// and //[[CL:Glossary:satisfy the test|satisfying the test]]// have been replaced by //newitem//. **substitute**, **substitute-if**, and **substitute-if-not** return a //sequence// which can share with //sequence// or may be //[[CL:Glossary:identical]]// to the input //sequence// if no elements need to be changed. **nsubstitute** and **nsubstitute-if** are required to **[[CL:Macros:setf]]** any **[[CL:Functions:car]]** (if //sequence// is a //[[CL:Glossary:list]]//) or **[[CL:Functions:aref]]** (if //sequence// is a //[[CL:Glossary:vector]]//) of //sequence// that is required to be replaced with //newitem//. If //sequence// is a //[[CL:Glossary:list]]//, none of the //[[CL:Glossary:cdrs]]// of the top-level //[[CL:Glossary:list]]// can be modified. ====Examples==== <blockquote> (substitute #\. #\Space "0 2 4 6") <r>"" </r> (substitute 9 4 '(1 2 4 1 3 4 5)) <r>(1 2 9 1 3 9 5) </r> (substitute 9 4 '(1 2 4 1 3 4 5) :count 1) <r>(1 2 9 1 3 4 5) </r> (substitute 9 4 '(1 2 4 1 3 4 5) :count 1 :from-end [[CL:Constant Variables:t]]) <r>(1 2 4 1 3 9 5) </r> (substitute 9 3 '(1 2 4 1 3 4 5) :test #'>) <r>(9 9 4 9 3 4 5)</r> (substitute-if 0 #'[[CL:Functions:evenp]] '((1) (2) (3) (4)) :start 2 :key #'[[CL:Functions:car]]) <r>((1) (2) (3) 0) </r> (substitute-if 9 #'[[CL:Functions:oddp]] '(1 2 4 1 3 4 5)) <r>(9 2 4 9 9 4 9) </r> (substitute-if 9 #'[[CL:Functions:evenp]] '(1 2 4 1 3 4 5) :count 1 :from-end [[CL:Constant Variables:t]]) <r>(1 2 4 1 3 9 5)</r> ([[CL:Macros:defparameter]] *some-things* ([[CL:Functions:list]] 'a 'car 'b 'cdr 'c)) <r>*SOME-THINGS*</r> (nsubstitute-if "function was here" #'fboundp *some-things* :count 1 :from-end [[CL:Constant Variables:t]]) <r>(A CAR B "function was here" C)</r> *some-things* <r>(A CAR B "function was here" C) </r> ([[CL:Macros:defparameter]] *alpha-tester* ([[CL:Functions:copy-seq]] "ab ")) <r>"ab " </r> (nsubstitute-if-not #\z #'[[CL:Functions:alpha-char-p]] *alpha-tester*) <r>"abz" </r> *alpha-tester* <r>"abz" </r> </blockquote> ====Side Effects==== **nsubstitute**, **nsubstitute-if**, and **nsubstitute-if-not** modify //sequence//. ====Affected By==== None. ====Exceptional Situations==== Should be prepared to signal an error of type type-error if //sequence// is not a //[[CL:Glossary:proper sequence]]//. ====See Also==== * **[[CL:Functions:subst|Function SUBST]]** * **[[CL:Functions:nsubst|Function NSUBST]]**, {\secref\ConstantModification}, {\secref\TraversalRules} ====Notes==== If //sequence// is a //[[CL:Glossary:vector]]//, the result might or might not be simple, and might or might not be //[[CL:Glossary:identical]]// to //sequence//. The **'':test-not''** //[[CL:Glossary:argument]]// is deprecated. The functions **substitute-if-not** and **nsubstitute-if-not** are deprecated. **nsubstitute** and **nsubstitute-if** can be used in for-effect-only positions in code. Because the side-effecting variants (//e.g.// **nsubstitute**) potentially change the path that is being traversed, their effects in the presence of shared or circular structure may vary in surprising ways when compared to their non-side-effecting alternatives. To see this, consider the following side-effect behavior, which might be exhibited by some implementations: <blockquote> (defun test-it (fn) (let ((x (cons 'b nil))) (rplacd x x) (funcall fn 'a 'b x :count 1))) (test-it #'substitute) → (A . #1=(B . #1#)) (test-it #'nsubstitute) → (A . #1#) </blockquote> \issue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE} \issue{TEST-NOT-IF-NOT:FLUSH-ALL} \issue{TEST-NOT-IF-NOT:FLUSH-ALL} \issue{SUBSEQ-OUT-OF-BOUNDS} \issue{RANGE-OF-START-AND-END-PARAMETERS:INTEGER-AND-INTEGER-NIL} \issue{RANGE-OF-COUNT-KEYWORD:NIL-OR-INTEGER} \issue{RANGE-OF-COUNT-KEYWORD:NIL-OR-INTEGER} \issue{REMF-DESTRUCTION-UNSPECIFIED:X3J13-MAR-89} \issue{CONSTANT-MODIFICATION:DISALLOW}