Use COUNTW().
First let's convert your listing into an actual dataset.
data have;
input ID Var1 :$40. Var1Count :$20.;
cards4;
1 abc;bde;cf 1;2;5
2 x;yz 3;1
3 a;x 2;7
4 cf;bdx;yz 6;3;2
5 . .
6 x 1
7 abc 3
8 xz;adk 2;8
9 a 3
10 bc;bd 2;1
;;;;
You will need to decide how long to make the NEW var1 variable. For this example let's set the old one to length $40 and the new on to $20. Let's make the new count variable numeric instead of character.
Now just use a DO loop to output each pair of values.
data want;
set have;
length _var1 $20 count 8 ;
do index=1 to countw(var1,';');
_var1 = scan(var1,index,';');
count = input(scan(var1count,index,';'),32.);
output;
end;
keep id _var1 count;
rename _var1=Var1 count=Var1Count ;
run;
Result
If your original string actually have those extra spaces after the semicolons then you will probably want to add in a LEFT() function call to remove them.
_var1 = left(scan(var1,index,';'));
You might want to also keep the INDEX variable so you know the original order the values were in inside the character strings.