正規表現でパターンマッチングを行い、マッチした数を返すマクロ

アクセス数とか見てみると、DS2系の記事がぶっ飛ぶほど人気なくてちょっと笑えます。
DS2凄いし、便利だし、今後の解析環境的にシフトしていくと思うんですけど、なかなかね。
もしちょっとでも興味のある方は今年のユーザー総会でDS2入門があるはずなので是非。

たまにはDS2以外の話でもと思っていたところ、いつ作ったかわからない便利マクロがでてきたので、ちょっと紹介します。

SASではPerlの正規表現が使用でき、わりと色んな所で紹介されているので利用している方も多いと思います。(2バイト文字に対してダメダメなので使えないケースも多いですが)

SASで正規表現-世界の切りとり方
http://d.hatena.ne.jp/O_Kohsuke/20141216/1419430432

【SAS】正規表現の取り扱い-ネットをさまよう実験室
http://tetchi-kun.hatenablog.com/entry/2015/01/13/183205

正規表現-Welcome to データ分析・マイニングの世界 by SAS
http://wikiwiki.jp/cattail/?%C0%B5%B5%AC%C9%BD%B8%BD

いろんな関数が用意されてるんですが、テキスト中に正規表現でマッチする部分が
いくつあるかをカウントする関数がありそうでなかったので、作ってみました。
多分正しくいけるはずですが間違ってたらご指摘ください

%macro prxcount (pattern, text, countvar);
 %local prx start stop pos length;
 %let prx = prxcount__prx_&sysindex;
 %let start = prxcount__start_&sysindex;
 %let stop = prxcount__stop_&sysindex;
 %let pos = prxcount__pos_&sysindex;
 %let length = prxcount__len_&sysindex;

 &prx = prxparse (&pattern);
 &start = 1;
 &stop = length (&text);
 &countvar. = 0;

 do while (&start <= &stop);
  call prxnext (&prx, &start, &stop, &text, &pos, &length);
  if &pos < 1 then leave;
  &countvar+1;
 end;

 drop prxcount__:;

%mend;

例えば

data A1;
text='cat rat bat pat';
%prxcount ("/[crb]at/",text, count1);
%prxcount ("/c.t/",text, count2);
run;

とすると、count1はcかrかbで始まって、次がatの部分なので3
count2はcの次が任意の一文字で、その次がtなのでcatの部分のみのマッチで1







となります。

肝になっている「call prxnext」ルーチンは
文字列内でパターンの一致があった位置と長さを都度指定した変数に返していくコールルーチンです。
詳しくはSASの公式を参照してください。
http://support.sas.com/documentation/cdl_alternate/ja/lefunctionsref/67960/HTML/default/n1obc9u7z3225mn1npwnassehff0.htm

パターンマッチしなくなった際に第4引数が0になるので、そこに行くまでループしてカウントしていくイメージです。


0 件のコメント:

コメントを投稿