BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Yoko
Obsidian | Level 7

Hello, 

 

I have character strings which look like: 20012, 24012, 20021, 28021, 20040, etc.

I want to select character strings whose last 3 characters are 012 or 040, for example, using %let statement (e.g., %let valid = )

That is, 20012, 24012, and 20040 should be selected in this example. 

Can anybody help me completing the let macro statement? 

 

Thank you, 

 

Yoko

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26
data have;
input string $;
cards;
20012
24012
20021
28021
20040
;
data want;
    set have;
    if left(reverse(string)) in :('210','040') then output;
run;

 

No macros needed. Please note that the IF statement requires a colon before ('210','040') which then tests if the reverse of the string starts with these values, and if it starts with these values, then the un-reversed string ends with the reverse of these values. Please note that I am testing against ('210','040') which is the reverse of what you asked for (you asked for: ends with 012 or 040), but it works in this application because I am testing the reverse strings.

--
Paige Miller

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26
data have;
input string $;
cards;
20012
24012
20021
28021
20040
;
data want;
    set have;
    if left(reverse(string)) in :('210','040') then output;
run;

 

No macros needed. Please note that the IF statement requires a colon before ('210','040') which then tests if the reverse of the string starts with these values, and if it starts with these values, then the un-reversed string ends with the reverse of these values. Please note that I am testing against ('210','040') which is the reverse of what you asked for (you asked for: ends with 012 or 040), but it works in this application because I am testing the reverse strings.

--
Paige Miller
Yoko
Obsidian | Level 7

Thank you for your suggestion. 

This is a part of a macro, so I have use %let. 

I'll incorporate your suggestion to something like this:

 

%let valid = ;

data _null_;

set have;

if left(reverse(string)) in :('210','040') then output;
run;

 

I hope this works. 

 

Thank you, 

 

Yoko

 

 

jklaverstijn
Rhodochrosite | Level 12

A macro solution could be obtained by marrying the wonderful %sysfunc() and prx*() functions. This works for me:

%let string=20040;
%let regex=/012$|040$/;
%let regid=%sysfunc(prxparse(&regex));
%put &=regid;
%let valid = %sysfunc(prxmatch(&regid, &string));
%put &=valid;

The code could be further condensed but this is the most descriptive.

%let string=20040;
%let valid = %sysfunc(prxmatch(/012$|040$/, &string));
%put &=valid;

The macro variable "valid" has a value of 0 (zero) if there is no match or a positive integer indicating startposition of the pattern searched for.

 

Needless to say I am a fan of the prx functions and highly recommend them in these situations.

 

Hope this helps,

- Jan.

Reeza
Super User

You haven't clarified your question enough. Are you strings values in a data set? Are they in a macro variable?
What do you the macro variable created to be? What are you going to use it for?

Ksharp
Super User
data have;
input string $;
cards;
20012
24012
20021
28021
20040
;

%let valid = 012 040 ;
data want;
    set have;
    if findw("&valid",strip(substrn(string,length(string)-2)));
run;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 919 views
  • 2 likes
  • 5 in conversation