Hello - trying to compare the substr function to a perl reg expressions for searching for a string pattern across multiple variables. For whatever reason it seems like the array is only searching across one of the fields and then stopping but it works when using substr function. Is there additional syntax that needs to be added for this to work? The example below is simple, so it's fine to use SUBTR but there are cases where Perl Reg Expressions can really reduce the amount of logic.
Note: &dx_field refers to a list of 26 variables
First Array - using SUBSTR searches across all variables (This works!):
ARRAY TEST {*} $ &DX_FIELD;
DO i=lbound(TEST) TO hbound(TEST);
IF (substr(TEST{i},1,3) = ("J11")) then flu=1 ;
END;
Second Array - uses Perl Reg Expression - only produces a match when the first variable within &dx_field matches:
ARRAY TEST2 {*} $ &dx_field;
DO i=lbound(TEST2) TO hbound(TEST2);
IF PRXMATCH("/(J11)/",TEST2[i]) THEN
FLU2 =1 ;
LEAVE;
END;
ARRAY TEST2 {*} $ &dx_field; DO i=lbound(TEST2) TO hbound(TEST2); IF PRXMATCH("/(J11)/",TEST2[i]) THEN do; FLU2 =1 ; LEAVE; end; /* of the IF test result*/ END;
How to use the LEAVE to quit the loop when you find the first match. Not quit in the first iteration of the loop.
Works fine for me.
data have;
input (dx1-dx3) ($) ;
cards;
J11 . .
. J11 .
. xJ11 .
;
data want;
set have;
arrary test dx1-dx3;
flu1=0;
flu2=0;
do i=1 to dim(test) while (not flu1);
flu1 = test[i]=:'J11';
end;
do i=1 to dim(test) while (not flu2);
flu2 = 0 < PRXMATCH("/(J11)/",test[i]) ;
end;
run;
proc print;
run;
Results:
Obs dx1 dx2 dx3 flu1 flu2 i 1 J11 1 1 2 2 J11 1 1 3 3 xJ11 0 1 3
Notice also that you regex expression is NOT the same as your other test as it is looking for J11 any where in the string instead of only at the start.
Your second example has an unconditional LEAVE statement inside the loop. So regardless of the value of the first array element, the loop is only applied to the first element.
Drop the LEAVE. Perhaps you want to use the UNTIL condition in your DO statements, as in
ARRAY TEST {*} $ &DX_FIELD;
DO i=lbound(TEST) TO hbound(TEST) until (flu=1);
IF (substr(TEST{i},1,3) = ("J11")) then flu=1 ;
END;
or
ARRAY TEST2 {*} $ &dx_field;
DO i=lbound(TEST2) TO hbound(TEST2) until (flu2=1);
IF PRXMATCH("/(J11)/",TEST2[i]) THEN
FLU2 =1 ;
END;
ARRAY TEST2 {*} $ &dx_field; DO i=lbound(TEST2) TO hbound(TEST2); IF PRXMATCH("/(J11)/",TEST2[i]) THEN do; FLU2 =1 ; LEAVE; end; /* of the IF test result*/ END;
How to use the LEAVE to quit the loop when you find the first match. Not quit in the first iteration of the loop.
Well - I'm happy to see the solution was simple. Many thanks!
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.