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!

Catch up on SAS Innovate 2026

Dive into keynotes, announcements and breakthroughs on demand.

Explore 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
  • 12 replies
  • 10345 views
  • 4 likes
  • 3 in conversation