I have a string like
a='a, b, cd, ef, gdj'
How to find 3rd comma
I want 3rd position for above
Data
DATA WORK.HAVE;
a='a, b, cd, ef, gdj';
NEWVar=SCAN(a,3);
RUN;
Result:
a NEWVar a, b, cd, ef, gdj cd
Hope this helps
This works if you want to know which position the 3rd comma is in. Stored in the third_loc var:
data temp(drop= i);
a='a, b, cd, ef, gdj';
do i = 1 to length(a);
if substr(a,i,1) = "," then comma_cnt+1;
if comma_cnt=3 then do;
third_loc=i;
output;
stop;
end;
end;
run;
Register today and join us virtually on June 16!
sasglobalforum.com | #SASGF
View now: on-demand content for SAS users
If you were looking for the actual location of the literal third comma punctuation in the text and not the third value (delimited by the commas), you could also use this logic:
data WORK.Have;
a='a, b, cd, ef, gdj';
call scan(a,4,pos,len,',');
pos=pos-1;
drop len;
run;
resulting output:
Obs a pos 1 a, b, cd, ef, gdj 9
Showing that the 3rd comma (',') was the 9th character in that text string
ref link to call scan: Sample 41355: Find the nth delimiter in a character string
This is a much better solution than mine. I user an &iterator in scan so much that I forget you can just say "give me the nth value"!
Register today and join us virtually on June 16!
sasglobalforum.com | #SASGF
View now: on-demand content for SAS users
Another way:
data _null_;
A='a, b, cd, ef, gdjh';
POS=length(prxchange('s/(([^,]*,){3}).*/\1/',1,A));
put POS=;
run;
POS=9
This expression reads: Find a group composed of: ( start of group ([^,]*,) anything-not-a-comma repeated as required then a comma [^,] * , {3} that combination (not comma then comma) appears thrice ) end of group .* the group is followed by all remaining characters \1 the second RegEx parameter asks that we only keep the group we matched i.e. we keep the three NotComma+Comma groups Because we discard everything after the third comma, the length function gives us the position we want.
Were any of the responses provided suitable as a solution to your problem? If so, please mark that post as the solution so that your post will close out as solved. Thanks.
I actually do like the CALL SCAN and regexen solutions better. But if you wanted to do it in a loop limited to 3 iterations, I can't help but suggest this:
data _null_ ;
retain s 'a, b, cd, ef, gdjh' ;
_s = s ;
do i = 1 to 3 ;
pos = findc (_s, ",") ;
substr (_s, pos, 1) = "" ;
end ;
put pos= ;
run ;
Kind regards
Paul D.
Yet another approach:
DATA WORK.HAVE;
a='a, b, cd, ef, gdj';
pos=0;
do i=1 to 3;
pos=findw(a,',',pos+1,',','K');
end;
drop i;
RUN;
findw finds "words"
The 1st argument is the string to search.
The 2nd argument defines the "word" to find (a comma).
The 3rd argument defines the starting position for the search. Needed to loop and find the 3rd comma.
The 4th argument defines the delimiters that separate words. In this case the delimiter is also the word we're searching for.
The 5th argument "keeps" the delimiter, i.e. reverses the meaning. A comma is now not treated as a delimiter.
Another approach (similar to hashman's but without the substr):
DATA WORK.HAVE;
a='a, b, cd, ef, gdj';
pos=0;
do i=1 to 3;
pos=findc(a,',',pos+1);
end;
drop i;
RUN;
P.S.: What are you really trying to do? I doubt you want the position of the 3rd comma; instead, what do you want to do with that position?
Neat! I like your FINDC approach better, but actually both are better than the SUBSTR pseudo-function known to be notoriously slow.
@hashman wrote:
Neat! I like your FINDC approach better, but actually both are better than the SUBSTR pseudo-function known to be notoriously slow.
Yeah, I like the FINDC approach better myself.
I started with FINDW, mistakenly thought FINDC didn't have the start position parameter, hit the doc, then decided to post both approaches.
What would be nice is a parameter to "find the Nth occurrence" of [character|word] in FINDC | FINDW. That's where @ChrisNZ 's solution is cool, but I doubt most folks would come up with that (but then Chris isn't "most folks" 😉 ). I suspect the OP will have to hit the Perl Regex docs to understand that (really cool) solution.
Ha @ScottBass! Bring on the compliments!
I just don't tire of them somehow! 😉
I feel like I have to add a few lines to explain the RegEx now.
@ChrisNZ : But indeed.That would't hurt a bit.
@ChrisNZ : Thanks 1e6!
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.
Ready to level-up your skills? Choose your own adventure.