Hello everyone,
I would like to get the number of items separated by a "|" (or another special character(s) like "||", "//" etc...) in a string macro variable. I tried the following code without success :
%let sentences=%unquote(%str(Première phrase d'essai|Deuxième phrase d'essai|Troisième phrase d'essai|Quatrième phrase d'essai));
%let ct_sentences=%sysfunc(countw(&sentences.), %str(|) )) ;
%put ===========> &ct_sentences.;
The macro variable &ct_sentences.
is equal to 12. How to fix this code in order to get the real number of 4 sentences ? Would you know any SAS functions that are more appropriates please ? Would you have any frame of code ?
Thank you in advance.
Best regards
Hi @Olscream Not sure why you want to macro quote that in my opinion is not necessary.
%let sentences=Première phrase d'essai|Deuxième phrase d'essai|Troisième phrase d'essai|Quatrième phrase d'essai;
%let ct_sentences=%sysfunc(countw(&sentences, %str(|)) ) ;
%put &=ct_sentences.;
174 %put &=ct_sentences.;
CT_SENTENCES=4
Alternatively, a %bquote usage would give you a clean log:
183 %let sentences=%bquote(Première phrase d'essai|Deuxième phrase d'essai|Troisième phrase
183! d'essai|Quatrième phrase d'essai);
184
185 %let ct_sentences=%sysfunc(countw(&sentences, %str(|)) ) ;
186
187 %put &=ct_sentences.;
CT_SENTENCES=4
Hi @Olscream Not sure why you want to macro quote that in my opinion is not necessary.
%let sentences=Première phrase d'essai|Deuxième phrase d'essai|Troisième phrase d'essai|Quatrième phrase d'essai;
%let ct_sentences=%sysfunc(countw(&sentences, %str(|)) ) ;
%put &=ct_sentences.;
174 %put &=ct_sentences.;
CT_SENTENCES=4
Alternatively, a %bquote usage would give you a clean log:
183 %let sentences=%bquote(Première phrase d'essai|Deuxième phrase d'essai|Troisième phrase
183! d'essai|Quatrième phrase d'essai);
184
185 %let ct_sentences=%sysfunc(countw(&sentences, %str(|)) ) ;
186
187 %put &=ct_sentences.;
CT_SENTENCES=4
That's right. I should have mentioned that at least in this case tokenisation doesn't get impacted. Also, %bquote(') is cleaner than %str(%') in my opinion.
%let ct_sentences=%sysfunc(countw(&sentences.,|)) ; %put ===========> &ct_sentences.;
you have the %str outside of the Countw function parameters and for a single character like this %str is not needed.
So you have found a bug (feature?) of %SYSFUNC(). If you give it gibberish like | for the format argument it does not generate an error message.
You essentially ran this code:
940 %put %sysfunc(countw(one two|three four|five),|); 5
So you asked %SYSFUNC() to run the COUNTW() function on the string using the normal set of delimiters and format the result using a pipe character as the format definition. It just ignored the pipe character and simply formatted the resulting integer into the normal character string it would use to display the number 5.
If you want to use | as the delimiter than pass it to the COUNTW() function and not to the %SYSFUNC() macro function.
941 %put %sysfunc(countw(one two|three four|five,|)); 3
You should probably leave the quoting on your messy string. Otherwise any commas or unbalanced quotes are going to confuse the macro processor.
You cannot use two character strings as the delimiter with the COUNTW() function. But look at the modifiers, especially the M and Q modifiers.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.