Thursday, January 20, 2011

How to report the position of a given character inside a string

/*******************************************************************
  SAS: How to report the position of a given character inside a string
  e.g.: Here have a tring abc_de_fg_ac_ff, we want to get the position
  of '_' in the string. That is, we want to get 4, 7, 10, 13

  In the following two methods are given, the first one using macro. It
  works like this: First, count how many '_' are there in the string.
  Then scan data until find the first '_', report its position. Then from
  this position, scan the rest string for the second one. And so on.

  The second method using data step. Scan the string, when meets '_',
  then report its position. This is easier to understand and code.
*********************************************************************/

******************  Method One   ********************************;

%macro ss(str,dlm);
  %let stt=1;
  %let pos=0;
  %do i=1 %to %sysfunc(count(&str,%str(&dlm))) %by 1;
     %let pos=%eval(%index(%substr(&str,&stt),&dlm)+&stt-1);
        %let stt=%eval(&pos+1);
        %put &pos;
   %end;
%mend ss;

%ss(abc_de_fg_ac_ff,_)


*****************  Method Two **********************************;

data s1;
  str='abc_de_fg_ac_ff';
run;

data s2;
  set s1;
  do i = 1 to length(str);
    if substr(str,i,1)="_" then put  i;
  end;
run;

2 comments:

  1. 第一个算法执行的结果:

    首先,count算出总共有4个"_"。 所以循环从1到4;

    其次,第一次,substr函数取出全部string,abc_de_fg_ac_ff,index发现第四位是“_”。记录下来pos=4,同事stt=5。

    第二次,substr取出第五位开始的string:de_fg_ac_ff,然后index发现第三位是"_",所以pos=7,同时stt=8

    第三次,……

    一次类推

    ReplyDelete
  2. 第二个算法执行的结果:

    length函数得到string长度为15. 所以循环15次。从位置i开始用substr函数每次扫描一个字符长度, substr(str,i,1)。如果得到“_”,就记录下i的位置。否则继续。直到扫描完整个字符。

    两个算法都用了substr,但是用的效果却是不一样

    ReplyDelete