2019年5月16日木曜日

SUBSTR vs SUBSTRN




以下記事で「SUBSTRN関数」を紹介しました。
文字列を抽出するSUBSTRN関数


同じような機能で「SUBSTR関数」ってのもあり、皆さんはよくこちらを使うと思います。
では「SUBSTR関数」と「SUBSTRN関数」がどう違うのか、比較してみたいと思います。




1. 「SUBSTR」にしかない機能


  • 指定した位置の文字を置換する事ができる(むかし書いた記事「SUBSTR関数の小技」でも紹介)
data test;
    length x $3.;
    x = "abc";
    substr( x, 2, 1 ) = "X";
run;





2. 「SUBSTRN」にしかない機能


  • 第1引数に数値変数を指定した場合、自動でBEST32形式の文字値に変換されて、抽出が行われる。
data test2;
    length x 8. y $10.;
    x = 123;
    y = substrn( x, 2, 2 );
run;

ちなみに数値を文字値に変換すると「                             123」みたいに前方に余計な半角スペースが入ってしまう事があるけど、SUBSTRNは文字値に変換する時にこの余計な半角スペースも取り除いてくれます。




3. 変数のLENGTHを越える位置の文字抽出


/* SUBSTR */
data test;
    length x $3. y1 y2 $10.;
    x = "abc";
    y1 = substr( x, 1, 5 );
    y2 = substr( x, 5, 1 );
run;






/* SUBSTRN */
data test2;
    length x $3. y1 y2 $10.;
    x = "abc";
    y1 = substrn( x, 1, 5 );
    y2 = substrn( x, 5, 1 );
run;




上の例では、変数Xのlengthが「3」なのに対して、「substr(x,1,5)」や「substr(x,5,1)」みたいにlengthを飛び越える位置の文字を抽出しようとしています。


「SUBSTR」も「SUBSTRN」も結果は一緒ですが、
  • 「SUBSTR」はログに「NOTE: 関数SUBSTR(行 xx カラム x)の第x引数は無効です。」と出ます。
  • 「SUBSTRN」はこのNOTEメッセージが出ません。




4. 抽出開始位置に0以下を指定した場合


/* SUBSTR */
data test3;
    length x $3. y $10.;
    x = "abc";
    y = substr( x, -1, 4 );
run;






/* SUBSTRN */
data test4;
    length x $3. y $10.;
    x = "abc";
    y = substrn( x, -1, 4 );
run;




上の例では、「substr(x,-1,4)」というように抽出を開始する位置にマイナスの値を指定しています。

  • 「SUBSTR」はマイナスの位置を認識できず、ログに「NOTE: 関数SUBSTR(行 xx カラム x)の第2引数は無効です。」と出て第2引数が無効となり、結果は欠損値になります。
  • 「SUBSTRN」は以下のようにマイナス方向の位置も認識できるようです。


「-1」の位置から「4バイト」を抽出するんで「ab」が返されるわけですね。





5. 抽出する長さに0以下を指定した場合


/* SUBSTR */
data test5;
    length x $3. y $10.;
    x = "abc";
    y = substr( x, 1, -1 );
run;






/* SUBSTRN */
data test6;
    length x $3. y $10.;
    x = "abc";
    y = substrn( x, 1, -1 );
run;



上の例では、「substr(x,1,-1)」というように抽出する長さにマイナスの値を指定しています。

  • 「SUBSTR」はマイナスの長さを認識できず、ログに「NOTE: 関数SUBSTR(行 xx カラム x)の第3引数は無効です。」と出て第3引数が無効となり、結果は第2引数に指定した抽出開始位置から文字の終わりまでが抽出されます。
  • 「SUBSTRN」もマイナスの長さを認識できず、こちらはログのNOTEメッセージは出ないものの、結果は欠損値になります。



以上、5つに分けて比較してみましたが、特に1~3は覚えとくと便利です。4~5は細かい話なんで余裕あったら覚えとけばいいと思います。



0 件のコメント:

コメントを投稿