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

Hi, I wanted to extract pact of the characters from a string which has delimiter '_'. The string is like this:

'abcd_ggg_fff_1234'

My question is: is there a single step to get 'ggg_fff" from that string, or have to do it in two steps?

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

Or 

 



data have;
input str $30.;
cards;
abcd_ggg_fff_1234
abcd_ttt_www_1234
qadc_hhh_lll_4321
dret_eee_1278
;


data want;
set have; 
call scan(str, 1, p, l,'_');
call scan(str, -1, position, length,'_');
want=substr(str,l+2,position-(l+3));
drop p: l:;
run;

View solution in original post

12 REPLIES 12
Jagadishkatam
Amethyst | Level 16

please try perl regular expression

 

data have;
x='abcd_ggg_fff_1234';
y=prxchange('s/(\w+)(ggg_fff)(.\d+)/$2/',-1,x);
run;
Thanks,
Jag
leehsin
Quartz | Level 8

Thanks, Jagadishkatam! But I have more strings with different middle parts:

 

'abcd_ggg_fff_1234'

'abcd_ttt_www_1234'

'qadc_hhh_lll_4321'

'dret_eee_1278'

 

I just want to do the general removal of prefix and suffix for all strings, not for a specific one.

 

Thank you!

novinosrin
Tourmaline | Level 20

HI @leehsin 

 

Call scan 



data have;
input str $30.;
cards;
abcd_ggg_fff_1234
abcd_ttt_www_1234
qadc_hhh_lll_4321
dret_eee_1278
;


data want;
set have; 
call scan(str, 1, position, length,'_');
substr(str,1,length+1)=' ';
call scan(str, -1, position, length,'_');
substr(str,position-1)=' ';
drop position length;
run;
leehsin
Quartz | Level 8

Hi, novinosrin, thanks for the solution. So, one step is not feasible. How about I want to keep both the original string and the new string?

 

novinosrin
Tourmaline | Level 20

Hi @leehsin  My second version gives you both. Please review

novinosrin
Tourmaline | Level 20

Or 

 



data have;
input str $30.;
cards;
abcd_ggg_fff_1234
abcd_ttt_www_1234
qadc_hhh_lll_4321
dret_eee_1278
;


data want;
set have; 
call scan(str, 1, p, l,'_');
call scan(str, -1, position, length,'_');
want=substr(str,l+2,position-(l+3));
drop p: l:;
run;
leehsin
Quartz | Level 8

Great! This solved my problem! Thank you so much!

novinosrin
Tourmaline | Level 20

Hello @leehsin  Just to accept your challenge, here is a one step solution. It's not any faster or better but I loved your question.

 


data have;
input str $30.;
cards;
abcd_ggg_fff_1234
abcd_ttt_www_1234
qadc_hhh_lll_4321
dret_eee_1278
;


data want;
set have; 
want=substr(str,index(str,'_')+1, findc(str,'_','B')- (index(str,'_')+1));
run;

 

Also, Call scan is by far much faster than a regular expression for a simple problem like this unless your pattern really needs a regex

novinosrin
Tourmaline | Level 20

@leehsin   This linear approach is pretty quick

 

data have;
input str $30.;
cards;
abcd_ggg_fff_1234
abcd_ttt_www_1234
qadc_hhh_lll_4321
dret_eee_1278
;

data want;
set have;
length want $30;
do _n_=2 to countw(str,'_')-1;
want=catx('_',want,scan(str,_n_,'_'));
end;
run;
leehsin
Quartz | Level 8

Hi, novinosrin, 

 

Thank you for providing more solutions! These versatile ways will serve many kinds of scenarios. Thank you!

Jagadishkatam
Amethyst | Level 16
data have;
input text :$100.;
if countw(text,'_')=4 then y=prxchange('s/(\w+\_)(\w+\_\w+)(\_\d+)/$2/',-1,text);
else if countw(text,'_')=3 then y=prxchange('s/(\w+\_)(\w+)(\_\d+)/$2/',-1,text);
cards;
abcd_ggg_fff_1234
abcd_ttt_www_1234
qadc_hhh_lll_4321
dret_eee_1278
;
Thanks,
Jag
leehsin
Quartz | Level 8

Jagadishkatam, yours is another good solution. Maybe more codes needed if I want to automatically detect the numbers for countw to use.

 

Thank you!

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 12 replies
  • 5135 views
  • 4 likes
  • 3 in conversation