2017年5月7日日曜日

文字列の検索いろいろ:INDEX関数編



文字列の検索に使えるINDEX系の関数を紹介。



INDEX、INDEXC、INDEXW関数


シングルバイト(半角の英数など)の文字を対象とする場合、上記3つの関数を状況によって使い分けます。
(わりと気難しい関数なので、後段の解説や注意点も参照下さい)

data DT1;
     A  = "abc,def,ghi" ;
     B  = index( trimn(A) , "bc" );
     C  = indexc( trimn(A) , "ae" );
     D  = indexw( trimn(A) , "def" , "," );
run;
  A  
  B  
  C  
   
  abc,def,ghi    2  1  5


📝関数に指定した変数は、場合によって上記のように「TRIMN関数」で包む必要があります(理由はあとで解説)



解説

INDEX( trimn(A) , "bc")

第2引数の "bc" という文字列が変数Aの何バイト目に見つかったかを返す。
(見つからなかった場合は0を返す。)


INDEXC( trimn(A) , "ae" )

第2引数の "ae"を一字ずつ分解し、"a"または"e"という文字が変数Aの何バイト目に見つかったかを返す。
(見つからなかった場合は0を返す。)


INDEXW( trimn(A) , "def" , ",")

変数Aが、第3引数に指定したカンマ「,」区切りで格納されていると解釈される。
つまり変数Aの「abc,def,ghi」は「abc」「def」「ghi」という3つの単語があると解釈される。
この3つの単語のうち、第2引数の「def」と完全一致する単語が5バイト目に見つかったことを表しています。

また、例えば第3引数に「#@」と指定した場合「#」と「@」が区切り文字になります
(「#@」という一続きの文字列が区切り文字になるという意味ではない)

ちなみに変数Aが「abc, def, ghi」みたいに単語間にスペースが入る場合、「abc」「 def」「 ghi」という単語があると解釈し、第2引数の「def」と完全一致するものは無しと判定されてしまうので注意。

さらにもう1つ注意。第2引数の先頭または末尾に含まれる区切り文字は削除されます。
例えば「indexw( "abc@def@ghi", "@def@", "@" )」 は「indexw( "abc@def@ghi", "def", "@" )」という指定に置き換わる。




注意点
  • 日本語などのマルチバイト文字を含む場合は、以下記事の通りうまく動作しないのでご注意ください
  • 以下で解説している通り、場合によって「TRIMN関数」を併用する必要があります。
    • 文字値の末尾にある空白問題
    • 上記リンク記事で解説している通り、変数値の長さがLENGTHより短い場合、末尾に半角スペースが入るので、以下のように想定外の結果を返す場合があります。

/* 失敗例 */
data DT1;
     length A $20.;
     A  = "abc,def,ghi" ;
     B  = index( A , " " );
     C  = indexc( A , " " );
     D  = indexw( A , "ghi" , "," );
run;
  A  
  B  
  C  
   
  abc,def,ghi   12  12   0


てことで「TRIMN関数」で一時的に末尾の半角スペースを取り除いてやります。

/* 成功例 */
data DT1;
     length A $20.;
     A  = "abc,def,ghi" ;
     B  = index( trimn(A) , " " );
     C  = indexc( trimn(A) , " " );
     D  = indexw( trimn(A) , "ghi" , "," );
run;
  A  
  B  
  C  
   
  abc,def,ghi    0  0  9




KINDEX、KINDEXC関数


マルチバイト(日本語などの全角文字など)を含む文字を対象とする場合、頭に”K”がつく上記2つの関数を使います。

また上の方で解説した通り、
関数に指定した変数は、場合によって「TRIMN関数」で包む必要があります。

data DT2;
  A = "あいうえお";
  B = kindex( trimn(A),"うえ");
  C = kindexc( trimn(A),"あお");
run;
  A  
  B  
  C  
  あいうえお    3  1


解説

KINDEX( trimn(A) , "うえ")

第2引数の "うえ" という文字列が変数Aの何文字目に見つかったかを返す。
(見つからなかった場合は0を返す。)


KINDEXC( trimn(A) , "あお" )

第2引数の "あお"を一字ずつ分解し、"あ"または"お"という文字が変数Aの何文字目に見つかったかを返す。
(見つからなかった場合は0を返す。)



重要なポイント

頭に"K"の付く関数とそうでない関数の違いとして、、
INDEX系関数は何バイト目に見つかったかを返すのに対し、
KINDEX系関数は何文字目に見つかったかを返します。



0 件のコメント:

コメントを投稿