ラベル 正規表現 の投稿を表示しています。 すべての投稿を表示
ラベル 正規表現 の投稿を表示しています。 すべての投稿を表示

2014年8月20日水曜日

VERIFY(KVERIFY)関数の紹介




あまり日の目をみることがない「VERIFY関数」にスポットライトを当ててみたいと思います。



VERIFY関数

 VERIFY( 変数, "検索文字" )

  • 変数に対して、検索文字を含まない最初の位置(何バイト目か)を取得する。
  • 日本語などのマルチバイト文字には未対応です。



*** サンプルデータ ;
data DT1;
   length V1 $10.;
   V1 = "000A"; output;
   V1 = "00AB"; output;
   V1 = "ABCD"; output;
   V1 = "A000"; output;
run;

*** VERIFY関数を使う ;
data DT2;
   set DT1;
   V2 = verify( V1, "ABC" );
run;

 V1  V2  
  000A    1 
  00AB   1 
  ABCD    4 
  A000   2 

ここではV1に、「A」「B」「C」の文字を含まない最初の位置を返しています。
検索文字は「ABC」という文字を検索するのではなく、「A」「B」「C」と1バイトずつ検索していることに注意しましょう。



実践例

では、実際にVERIFYがよく使われるシチュエーション。
サンプルデータに対して、先頭の0を取った値が欲しいとします。

 V1  V2  
  000A   A  
  00AB  AB 
  ABCD   ABCD 
  A000  A000 


これを実現するには、正規表現を使うか、VERIFY関数がスマートなプログラムになるかなと思います。

data DT3;
  set DT1;

  length V2 V3 $10.;

  * 正規表現を使う例 ;
  V2 = prxchange("s/0*(.*)/$1/", 1, V1);

  * VERIFY関数を使う例 ;
  _VER = verify(V1, "0");
  if  _VER >=1  then V3 = substr(V1, _VER);
run;


簡単な説明となりますが、

正規表現の例では、PRXCHANGEという正規表現を使って置換処理をする関数で、先頭の0を抜いた文字に置き換えてます。

VERIFYを使う例では、まず0以外の文字が最初に出現する位置を取得して、SUBSTR関数でその位置からの文字を抜き出しています。



KVERIVY関数

こちらは日本語などのマルチバイト文字に対応しています。

 KVERIFY( 変数, "検索文字" )

  • 変数に対して、検索文字を含まない最初の位置(何文字目か)を取得する。
  • VERIFY関数が「何バイト目か」を取得するのに対し、KVERIFY関数は「何文字目か」を取得する事に注意。


*** サンプルデータ ;
data DT3;
   length V1 $20.;
   V1 = "あいうえお"; output;
   V1 = "あおいえい"; output;
run;

*** KVERIFY関数を使う ;
data DT4;
   set DT3;
   V2 = kverify( V1, "あお" );
run;

 V1  V2  
  あいうえお    2 
  あおいえい   3

V1に、「あ」「お」の文字を含まない最初の位置を返しています。
検索文字は「あお」という文字を検索するのではなく、「あ」「お」と1文字ずつ検索していることに注意しましょう。



わたし自身、VERIFY関数の面白い使い方をまだ探し中なので、こんな使い方できるよっていうのがあれば、教えてほしいです。


2014年2月25日火曜日

FORMATプロシジャで正規表現を使う。



「SAS9.3」から、
FORMATプロシジャのINVALUEステートメント内で、正規表現が使えるようになりました。

ただしこの機能はシングルバイト文字でのみ使用したほうが良さそうです。
(現状、日本語などのマルチバイト文字に対応していないようなのと、こちら」で取り上げた問題により意図した結果にならない可能性があるため)
 


INVALUEはインフォーマットを作成するステートメントです。
正規表現は詳しくない、、ので詳細は割愛します。。




*** サンプルデータ作成 *****;
data DT1;
  input V1$;
cards;
ad
ca
fd
;

*** INVALUEステートメントに正規表現を使う例 *****;
* ① ***;
proc format;
  invalue MYFMT1_
    '/[abc]{2}/'  (regexp) = 1
    '/[def]{2}/'  (regexp) = 2
    other = 3
  ;
run;

* ② ***;
data DT2;
  set DT1;
  V2 = input(V1, MYFMT1_.);
run;

データセット「DT2」
V1  V2
ad   3
ca   1
fd    2




解説

①まず正規表現を含むINVALUEステートメントを定義します。
以下の両端を「/」で囲んでるやつが正規表現。また「(regexp)」と書くことで、正規表現ですよ、と宣言してます。

'/[abc]{2}/'  (regexp) = 1


上記は、「a,b,c」のいずれかの2文字で構成されてる値だったら「1と表示する」と定義してます。


②INPUT関数でインフォーマットを指定して数値変換します。