BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
bentleyj1
Quartz | Level 8

I have a string containing multiple words.  Each word needs to go into a macro variable.  I'm sure I'm missing something, but how do I handle a word delimiters that consists of multiple characters?

Here is the string I have to work with.  Is there a way to use the scan function to pull out the words without first doing a whole lot of substringing to replace "_" with a single character like a comma?

CELL_TRGT_SEGMENT_CD"_"CELL_STATUS_CD "_"CELL_CREATIVE_CD"_"CELL_RPT_CD"_"CELL_FULFILL_GRP_CD

John

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

Another alternative that does not change the input uses INFILE magic and the DLMSTR infile statement option.  I do not see where/if the SCAN function has similar option.

%let string=CELL_TRGT_SEGMENT_CD"_"CELL_STATUS_CD "_"CELL_CREATIVE_CD"_"CELL_RPT_CD"_"CELL_FULFILL_GRP_CD;

filename FT15F001 temp;
data _null_;           
  
infile FT15F001 dlmstr='"_"' missover;
  
input @;
   _infile_ = symget('string');
   length word $64;
  
do i = 1 by 1 until(missing(word));
      input word:$64. @;
      put word=;
      end;
  
stop;
  
parmcards;
Necessary evil
;;;;
   run;

word=CELL_TRGT_SEGMENT_CD
word=CELL_STATUS_CD
word=CELL_CREATIVE_CD
word=CELL_RPT_CD
word=CELL_FULFILL_GRP_CD
word=

View solution in original post

9 REPLIES 9
Reeza
Super User

Scan can take multiple delimiters. You can also look at the modifiers section to add another delimiter.

Use single quote to include the quotation marks and _ in the list.

scan(word, i, '"_')

EDIT: I think I misunderstood your question. You only have 4 words separated by "_" each time?

If so I guess I'd go old school and use findw and substr.

Or PRX functions which I've successfully managed to avoid Smiley Happy

bentleyj1
Quartz | Level 8

When multiple delimiters are passed to the scan function it uses any one of them as the delimiter.

Astounding
PROC Star

So you have data that uses _ as both text and as part of a multi-character delimiter?

Like Reeza, I have avoided PRX functions and they may be a candidate.  But here is some DATA step code that could be used.  The 4 quote marks are a single quote, a double quote, and a single quote.

data _null_;

length word $ 32;

i=0;

do until (word=' ');

   i + 1;

   word = scan(string, i, '"');

   if word not in (' ', '_') then do;

      mv_counter + 1;

     call symputx ('mv' || left(put(mv_counter,3.)), word);

   end;

end;

run;

data_null__
Jade | Level 19

It looks to me more like you have delimiters in quoted sub-strings of string.  I think Q option on SCAN function will suffice.

%let string="CELL_TRGT_SEGMENT_CD"_"CELL_STATUS_CD "_"CELL_CREATIVE_CD"_"CELL_RPT_CD"_"CELL_FULFILL_GRP_CD";

data _null_;
   string=symget(
'string');
   length word $64;
  
do i = 1 by 1 until(missing(word));
      word = scan(string,i,'_','Q');
      put word=;
      end;
  
stop;
  
run;

word=
"CELL_TRGT_SEGMENT_CD"
word=
"CELL_STATUS_CD "
word=
"CELL_CREATIVE_CD"
word=
"CELL_RPT_CD"
word=
"CELL_FULFILL_GRP_CD"
word=
Astounding
PROC Star

Nice approach.  However, I think the problem starts out a little differently, using delimeters of:

"_"

The original string doesn't start or end with a quote.  But that can be rectified in your program by adding the double quotes around strip(string).  Might be necessary to remove quotes from WORD at the end, though.

data_null__
Jade | Level 19

I realized I've changed the input slightly but I think that can all be accommodated as you have outlined.

data_null__
Jade | Level 19

Another alternative that does not change the input uses INFILE magic and the DLMSTR infile statement option.  I do not see where/if the SCAN function has similar option.

%let string=CELL_TRGT_SEGMENT_CD"_"CELL_STATUS_CD "_"CELL_CREATIVE_CD"_"CELL_RPT_CD"_"CELL_FULFILL_GRP_CD;

filename FT15F001 temp;
data _null_;           
  
infile FT15F001 dlmstr='"_"' missover;
  
input @;
   _infile_ = symget('string');
   length word $64;
  
do i = 1 by 1 until(missing(word));
      input word:$64. @;
      put word=;
      end;
  
stop;
  
parmcards;
Necessary evil
;;;;
   run;

word=CELL_TRGT_SEGMENT_CD
word=CELL_STATUS_CD
word=CELL_CREATIVE_CD
word=CELL_RPT_CD
word=CELL_FULFILL_GRP_CD
word=
bentleyj1
Quartz | Level 8

Brilliant.   I wasn't aware of the infile statement's dlmstr= option. (it's been a long time since I've used INFILE.)  The way you use a temporary fileref and reset the _infile_ variable is vey clever.  Thanks for your help, and thanks to the other folks who took time to provide suggestions.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 9 replies
  • 11936 views
  • 1 like
  • 4 in conversation