/* Richard A. DeVenezia * www.devenezia.com */ /* * This was posted to SAS-L on August 6, 2003 * The thread was subject "Help with RXPARSE" * * Yan Lee wanted macro as follows: * %macro qword(string=, prefix=); * ... * %mend; * * %put %qword(string = jan feb march, prefix=2003); * the result of this should be: * '2003jan' '2003feb' '2003march' */ /* * Note: SAS call routines are invoked from macro using the * %SYSCALL() function and any macro variables involved with * the call need to contain data so there is a memory space * for the call routine to work in. */ %macro qword(string=, prefix=); %local rx pattern n bigstring; /* * $C+ * ----- * matches one or more consecutive SAS name characters, i.e. ($'0-9a-zA-Z_') * * to "'" &prefix.== "'" * ----- * replaces the matched substring with itself, prefaced with value of prefix and * enclosed in single quotes */ %let pattern = $C+ to "'" &prefix.== "'"; /* * get a handle to a parsed pattern */ %let rx = %sysfunc (rxparse ( &pattern )); /* * the maximum number of times we want to find and replace should be * a large enough number to mean all */ %let n = 999; /* * the transformed string will end up in bigstring, thus * we need to ensure bigstring has a length more than enough * to contain the transformed string. The length of bigstring * going into rxchange is the maximum length it will be coming * out (%syscall can not make macro variable values longer) */ %let bigstring = &string %sysfunc(repeat(%str( ), 1000)) z; /* bigstring is 1000 characters longer than string * big string is needed because macro vars passed to syscalled routines * have length of current value, thus, if rxchange needed to grow string, * it would not be able to. * the z at end of big string is need to ensure the 1000 spaces before it * are kept; if the z was not there the 1000 spaces created by the repeat * would be auto-trimmed during macro var assignment. * qsysfunc(repeat caused some weirdness, so it was avoided. * a null string causes bigstrings returned value to be a semi-colon (more weirdness) */ /* * perform the find and replace */ %syscall rxchange (rx, n, bigstring); /* * Very important: free up the rxparse handle */ %syscall rxfree (rx); /* * emit the value of bigstring */ &bigstring %mend; %put %qword(string = jan feb march, prefix=2003);