Date: Thu, 28 Oct 2010 11:09:06 -0500
Reply-To: "Data _null_;" <iebupdte@GMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Data _null_;" <iebupdte@GMAIL.COM>
Subject: Re: multi-character delimiter
In-Reply-To: <201010281542.o9SAndkP005071@willow.cc.uga.edu>
Content-Type: text/plain; charset=ISO-8859-1
Now I understand. :-)
What we "need" are options on the SCAN function similar to the infile options.
On Thu, Oct 28, 2010 at 10:42 AM, Chang Chung <chang_y_chung@hotmail.com> wrote:
> On Tue, 26 Oct 2010 17:22:16 -0400, Chang Chung <chang_y_chung@HOTMAIL.COM>
> wrote:
> ...
>>Given macro variable, test, as below:
>> %let text="typ}es": ]} "LAYO]UT":]} "Label": "LAYOUT";
>>I would like to extract all ']}' delimited words like:
>> "typ}es":
>> "LAYO]UT":
>> "Label": "LAYOUT"
>
> Thanks, Joe, Art, and Data _null_:
>
> Data _null_'s solution using the Q option on SCAN works, but it does
> because of the test input data happened to have all the delimited words in
> double quotes. The Q option has little to do with multi-character delimiter
> -- it lets scan function to ignore any delimiter characters inside of a
> double quoted string.
>
> As far as I know (correct me if incorrect), the only place where we have
> the multi-character delimiter support is the infile statement, which has
> dlmstr= and dlmsopt= options.
>
> Below is my try on taking advantage of this facility via a variant of the
> so called "the _infile_ magic" (see http://tinyurl.com/24qwpsg or
> http://www.listserv.uga.edu/cgi-bin/wa?A2=ind0904C&L=sas-
> l&P=R39919&D=0&H=0&O=T&T=1). It is incomplete and inefficient because it
> lacks parameter checks, isn't careful about macro quoting, and creates a
> temporary catalog with a one long-line source entry each time it is called.
> Still, it shows how can one take advantage of the multi-character delimiter
> support implemented in the infile statement.
>
> Code ran on 9.2 (TS1M0) on W32_VSPRO.
>
> Cheers,
> Chang
>
> %macro mscan(string, count, _word=word, dlmstr=%str( ), dlmsopt=T,
> file=noevil, catalog=work.catalog.necessaryEvil.source);
> /* evil but necessary to set the _infile_ buffer length long */
> filename &file "&catalog" lrecl=32767;
> data _null_;
> file &file;
> length s $32767;
> s = repeat ("x", 32767-1);
> put s;
> run;
> data _null_;
> infile &file dlmstr="&dlmstr" dlmsopt="&dlmsopt" truncover;
> input @1 @;
> _infile_ = %sysfunc(quote(%superq(string)));
> length w $32767;
> do i = 1 to &count while (i<32767); /* guards inf looping */
> input w $ @; /* trims leading blanks */
> end;
> call symput("&_word", trimn(w)); /* trims trailing blanks */
> run;
> filename noEvil clear;
> %mend mscan;
>
>
> %*-- notice that the second word now lacks doulbe quotes --*;
> %let instr="typ}es": ]} LAYO]UT:]} "Label": "LAYOUT";
> %let dlmstr=]};
> %let w1=; %let w2=; %let w3=;
> %mscan(&instr, 1, _word=w1, dlmstr=&dlmstr);
> %mscan(&instr, 2, _word=w2, dlmstr=&dlmstr);
> %mscan(&instr, 3, _word=w3, dlmstr=&dlmstr);
> %put *** &w1 *** &w2 *** &w3 ***;
> /* on log
> *** "typ}es": *** LAYO]UT: *** "Label": "LAYOUT" ***
> */
>
|