Hi Experts,
I have a variable i.e. Var1 and want to split it as shown in Want column below:
In Var1 all values do not have Spaces between words so need to insert a space inbetween.
data ana_pres.have;
input Var1 $30.;
datalines;
ABCReport
MainUsers
A-ABCTestReport
Overview(ABC)
ABC-I2.5.3
Report+DOS
ABC/DS Report
;
run;
HAVE | WANT |
ABCReport | ABC Report |
MainUsers | Main Users |
A-ABCTestReport | A-ABC Test Report |
Overview(ABC) | Overview (ABC) |
ABC-I2.5.3 | ABC -I2.5.3 |
Report+DOS | Report + DOS |
ABC/DS Report | ABC / DS Report |
Thanks
Hi,
Try this one (not perfect, but 90%)
data have;
input Var1 $30.;
datalines;
ABCReport
MainUsers
A-ABCTestReport
Overview(ABC)
ABC-I2.5.3
Report+DOS
ABC/DSReport
;
run;
data want;
set have;
length Var2 $ 60;
keep Var1 Var2;
array letters[60] $ 1 _temporary_;
array markers[3] $ 1 _temporary_ ('=' '+' '/');
i = 0;
do until(letters[i] = " ");
i+1;
letters[i] = char(Var1,i);
end;
i+(-1);
do i = 1 to i;
select;
when ( ('A' <= letters[i] <= 'Z') and ('A' <= letters[i+1] <= 'Z') )
do;
Var2 = strip(Var2) || letters[i] ;
end;
when ( ('a' <= letters[i] <= 'z') and not('a' <= letters[i+1] <= 'z') )
do;
Var2 = strip(Var2) || letters[i] || " " || letters[i+1];
i + 1;
end;
when ( ('A' <= letters[i] <= 'Z') and ('a' <= letters[i+1] <= 'z') )
do;
Var2 = strip(Var2) || " " || letters[i] || letters[i+1];
i + 1;
end;
otherwise Var2 = strip(Var2) || letters[i] ;
end;
end;
do i = 1 to dim(markers);
Var2 = compbl(tranwrd(Var2, markers[i], " "||markers[i]||' '));
end;
run;
But since collapsing spaces is irreversible function having general solution may not be doable 🙂
All the best
Bart
Hello,
The purpose of this forum is to give/get technical help regarding the SAS language.
Here your problem lacks clear specifications. You have to design unambiguous rules
to decide when and where spaces should be inserted and then, users of this forum
can help you implement your design in SAS. Your example does not make
that clear at all.
For instance, why "Overview" gives "Overview"and not "O verview" ?
Why "ABCReport" gives "ABC Report" and not "ABCR eport" ?
What should be done with non alphabetical characters surroundig uppercase
strings : "Overview(ABC)" gives "Overview( ABC )" or "Overview (ABC) " ?
This probably calls for PRX:
data have;
input Var1 $30.;
datalines;
ABCReport
MainUsers
A-ABCTestReport
Overview(ABC)
ABC-I2.5.3
Report+DOS
ABC/DS Report
;
run;
data want;
set have;
prxid1=prxparse('s/([A-Z,a-z])([A-Z][a-z])/$1 $2/');
prxid2=prxparse('s/([+,\/])/ $1 /');
prxid3=prxparse('s/\(/ (/');
call prxchange(prxid1,-1,Var1);
call prxchange(prxid2,-1,Var1);
call prxchange(prxid3,-1,Var1);
run;
The first regular expression inserts a space when you have a letter followed by a capital letter, followed by a non-capital letter.
The second inserts spaces around "+" and "/" (the latter is escaped with a backslash in the search string).
The third inserts a blank before "(".
But I am not sure what to do about the "-", in one case you precede "-" with a blank, in the other case you do not.
Hi,
Try this one (not perfect, but 90%)
data have;
input Var1 $30.;
datalines;
ABCReport
MainUsers
A-ABCTestReport
Overview(ABC)
ABC-I2.5.3
Report+DOS
ABC/DSReport
;
run;
data want;
set have;
length Var2 $ 60;
keep Var1 Var2;
array letters[60] $ 1 _temporary_;
array markers[3] $ 1 _temporary_ ('=' '+' '/');
i = 0;
do until(letters[i] = " ");
i+1;
letters[i] = char(Var1,i);
end;
i+(-1);
do i = 1 to i;
select;
when ( ('A' <= letters[i] <= 'Z') and ('A' <= letters[i+1] <= 'Z') )
do;
Var2 = strip(Var2) || letters[i] ;
end;
when ( ('a' <= letters[i] <= 'z') and not('a' <= letters[i+1] <= 'z') )
do;
Var2 = strip(Var2) || letters[i] || " " || letters[i+1];
i + 1;
end;
when ( ('A' <= letters[i] <= 'Z') and ('a' <= letters[i+1] <= 'z') )
do;
Var2 = strip(Var2) || " " || letters[i] || letters[i+1];
i + 1;
end;
otherwise Var2 = strip(Var2) || letters[i] ;
end;
end;
do i = 1 to dim(markers);
Var2 = compbl(tranwrd(Var2, markers[i], " "||markers[i]||' '));
end;
run;
But since collapsing spaces is irreversible function having general solution may not be doable 🙂
All the best
Bart
This could give you a start.
data have;
input Var1 $30.;
datalines;
ABCReport
MainUsers
A-ABCTestReport
Overview(ABC)
ABC-I2.5.3
Report+DOS
ABC/DS Report
;
run;
data want;
set have;
want=left(compbl(prxchange('s/([A-Z][a-z]+)/ \1 /',-1,var1)));
want=left(compbl(prxchange('s/(\W)/ \1 /',-1,want)));
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.