前のページ|次のページ

CALL SCANルーチン

文字列からn番目の単語の位置と長さを返します。

カテゴリ: 文字
操作: %SYSCALLマクロステートメントで呼び出されると、CALL SCANの引数から引用符が削除されます。詳細については、CALLルーチンと%SYSCALLマクロステートメントを使用するを参照してください。

構文

CALL SCAN(<string>, count, position, length <, <character-list> <, <modifier(s)>>>);

必須引数

count

CALL SCANルーチンが文字列内で選択する単語の番号を指定する整数値を使用するゼロ以外の数値の定数、変数または式です。たとえば、1の値は1番目の単語、2の値は2番目の単語を示します。次のルールが適用されます。

  • countが正の場合、CALL SCANは文字列の単語を左から右へ数えます。
  • countが負の場合、CALL SCANは文字列の単語を右から左へ数えます。

position

単語の位置を返す数値変数を指定します。countが文字列内の単語数を超えると、positionで返される値はゼロになります。countがゼロまたは欠損している場合、positionで返される値は欠損します。

length

単語の長さを返す数値変数を指定します。countが文字列内の単語数を超えると、lengthで返される値はゼロになります。countがゼロまたは欠損している場合、lengthで返される値は欠損します。

オプション引数

string

文字定数、変数または式を指定します。

character-list

文字のリストを初期化する任意の文字定数、変数または式を指定します。このリストは、単語を区切る区切り文字として使用する文字を決定します。次のルールが適用されます。

  • デフォルトでは、character-listのすべての文字が区切り文字として使用されます。
  • modifier引数でK修飾子を指定すると、character-listにないすべての文字が区切り文字として使用されます。
ヒント その他の修飾子を使用してcharacter-listにさらに文字を追加できます。

modifier

空白以外の各文字によってCALL SCANルーチンのアクションが変更される、文字定数、変数または式を指定します。空白は無視されます。次の文字を修飾子として使用できます。

aまたはA 文字のリストにアルファベット文字を追加します。
bまたはB count引数の符号に関係なく、左から右ではなく、右から左へ逆行スキャンします。
cまたはC 文字のリストに制御文字を追加します。
dまたはD 文字のリストに数字を追加します。
fまたはF 文字のリストにアンダースコアと英文字(VALIDVARNAME=V7を使用したSAS変数名内の有効な最初の文字)を追加します。
gまたはG グラフィック文字を文字リストに追加します。グラフィカル文字は、紙面に印刷するとイメージになる文字です。
hまたはH 文字のリストに水平タブを追加します。
iまたはI 大文字か小文字かは無視します。
kまたはK 文字のリストに含まれていないすべての文字を区切り文字として扱うようにします。つまり、Kを指定すると、文字リストに含まれている文字が、区切り文字として省略されることなく、戻り値内に保持されます。Kを指定しない場合、文字のリストに含まれているすべての文字が区切り文字として扱われます。
lまたはL 文字のリストに小文字を追加します。
mまたはM 複数の連続する区切り文字、およびstringstring引数の先頭または末尾の区切り文字が、長さがゼロの単語を参照するように指定します。M修飾子を指定しない場合、複数の連続する区切り文字は1つの区切り文字として扱われ、string引数の先頭または末尾の区切り文字は無視されます。
nまたはN 文字のリストに数字、アンダースコアおよび英文字(VALIDVARNAME=V7を使用したSAS変数名内に表示可能な文字)を追加します。
oまたはO character-list引数およびmodifier引数を、CALL SCANルーチンを呼び出すごとに処理するのではなく、1回だけ処理します。DATAステップでO修飾子を使用すると、character-list引数およびmodifier引数が変更されないループ内でCALL SCANを呼び出すとき、より迅速に実行できます。O修飾子はSASコード内のCALL SCANルーチンの各インスタンスに個別に適用され、CALL SCANルーチンのすべてのインスタンスで同じ区切り文字と修飾子が使用されるようにはなりません。
pまたはP 文字のリストに句読点を追加します。
qまたはQ 引用符で囲まれた部分文字列内の区切り文字を無視します。string引数の値に、一致しない引用符が含まれている場合、左から右へのスキャンでは、右から左へのスキャンとは異なる単語が生成されます。
sまたはS 文字のリストに空白文字(空白、水平タブ、垂直タブ、キャリッジリターン、ラインフィード、フォームフィード)を追加します。
tまたはT string引数およびcharacter-list引数から末尾の空白を取り除きます。両方の文字引数ではなく一方のみから末尾の空白を削除する場合は、CALL SCANルーチンでT修飾子を使用するかわりに、TRIM関数を使用します。
uまたはU 文字のリストに大文字を追加します。
wまたはW 文字のリストに印刷可能(書き込み可能)な文字を追加します。
xまたはX 文字のリストに16進文字を追加します。
ヒント modifier引数が文字定数の場合は引用符で囲みます。一組の引用符で複数の修飾子を指定します。引数modifierには、文字変数や文字式も指定できます。

詳細

"区切り文字"と"単語"の定義

区切り文字とは、単語を区切るために使用される複数の文字のどれかです。区切り文字はcharacter-list引数とmodifier引数で指定できます。
Q修飾子を指定すると、引用符で囲まれた部分文字列内の区切り文字は無視されます。
CALL SCANルーチンでは、"単語"とは次の特性すべてを持つ部分文字列を指します。
  • 左側が区切り文字または文字列の先頭で境界設定されている
  • 右側が区切り文字または文字列の末尾で境界設定されている
  • 区切り文字を含まない
文字列の先頭または末尾に区切り文字がある場合、または文字列に2つ以上の連続する区切り文字が含まれている場合、単語の長さがゼロになることがあります。ただし、CALL SCANルーチンでは、M修飾子を指定しなければ、長さがゼロの単語は無視されます。

ASCII環境とEBCDIC環境でデフォルトの区切り文字を使用する

CALL SCANルーチンで4つの引数のみを使用する場合、コンピュータでASCII文字またはEBCDIC文字が使われているかどうかによってデフォルトの区切り文字が異なります。
  • お使いのコンピュータでASCII文字が使用されている場合、デフォルトの区切り文字は次のようになります。
    空白 !$ % & ( ) * + , - ./ ; < ^ パイプ
    ^文字を含まないASCII環境の場合、CALL SCANルーチンではかわりに~文字を使用します。
  • お使いのコンピュータでEBCDIC文字が使用されている場合、デフォルトの区切り文字は次のようになります。
    空白 !$ % & ( ) * + , - ./ ; < ¬ | ¢ デフォルトの区切り文字
区切り文字とする文字を指定せずにmodifier引数を使用すると、使用される区切り文字はmodifier引数で定義される文字のみになります。この場合、ASCII環境とEBCDIC環境のデフォルトの区切り文字のリストは使用されません。つまり、修飾子はcharacter-list引数で明示的に指定された区切り文字のリストに追加します。修飾子は、デフォルトの修飾子のリストには追加しません。

M修飾子を指定してCALL SCANルーチンを使用する

M修飾子を指定すると、文字列内の単語数は文字列内の区切り文字数に1を足した数になります。ただし、Q修飾子を指定すると、引用符内の区切り文字は無視されます。
M修飾子を指定すると、次の条件を満たす場合、CALL SCANルーチンは正の位置と長さゼロを返します。
  • 文字列の先頭が区切り文字であり、ユーザーが最初のワードを要求した場合
  • 文字列の末尾が区切り文字であり、ユーザーが最後のワードを要求した場合
  • 文字列が2つの連続する区切り文字を含んでおり、ユーザーがこれら2つの区切り文字間にあるワードを要求した場合
カウントを文字列内の単語数より大きい絶対値に指定すると、CALL SCANルーチンはゼロの位置と長さを返します。

M修飾子を指定せずにCALL SCANルーチンを使用する

M修飾子を指定しない場合、文字列内の単語数は連続する非区切り文字の最大部分文字列数になります。ただし、Q修飾子を指定すると、引用符内の区切り文字は無視されます。
M修飾子を指定しない場合、CALL SCANルーチンは次のように動作します。
  • 文字列の先頭または末尾の区切り文字を無視する
  • 2つ以上の連続する区切り文字を単一の区切り文字として扱う
文字列に区切り文字しか含まれていない、またはカウントを文字列内の単語数より大きい絶対値に指定すると、CALL SCANルーチンはゼロの位置と長さを返します。

単語を文字列として検索する

CALL SCANルーチンを呼び出した後に指定した単語を文字列として検索するには、string引数、position引数およびlength引数を指定したSUBSTRN関数を使用します。
substrn(string, position, length);
CALL SCANはゼロの長さを返す可能性があるため、SUBSTR関数を使用するとエラーが発生することがあります。

NULL引数の使用

CALL SCANルーチンでは、文字引数をNULLに指定できます。NULL引数は長さがゼロの文字列として扱われます。数値引数はヌルにできません。

例1: 文字列内の単語をスキャンする

CALL SCANルーチンを使用して文字列内の単語の位置と長さを検索する方法の例を次に示します。
data artists;
   input string $60.;
   drop string;
   do i=1 to 99;
      call scan(string, i, position, length);
      if not position then leave;
      Name=substrn(string, position, length);
      output;
   end;
   datalines;
Picasso Toulouse-Lautrec Turner "Van Gogh" Velazquez
;
proc print data=artists;
run;
文字列内の単語のスキャン結果出力
文字列内の単語のスキャン結果出力

例2: 文字列内の最初と最後の単語を検索する

文字列内の最初と最後の単語をスキャンする例を次に示します。注:
  • カウントを負に指定すると、CALL SCANルーチンは右から左へスキャンします。
  • M修飾子が使用されていないため、先頭と末尾の区切り文字は無視されます。
  • 最終オブザベーションでは、文字列内のすべての文字が区切り文字であるため、単語は検出されません。
data firstlast;
   input String $60.;
   call scan(string, 1, First_Pos, First_Length);
   First_Word=substrn(string, First_Pos, First_Length);
   call scan(string, –1, Last_Pos, Last_Length);
   Last_Word=substrn(string, Last_Pos, Last_Length);
   datalines4;
Jack and Jill
& Bob & Carol & Ted & Alice &
Leonardo
! $ % & ( ) * + , - . / ;
;;;;
proc print data=firstlast;
   var First: Last:;
run;
文字列内の最初と最後の単語の検索結果出力
文字列内の最初と最後の単語の検索結果出力

例3: M修飾子を使用せずに文字列内のすべての単語を検索する

単語が検出されなくなるまで文字列を左から右へスキャンする例を次に示します。M修飾子が使用されていないため、CALL SCANルーチンは長さがゼロの単語は返しません。デフォルトの区切り文字に空白が含まれているため、CALL SCANルーチンはカウントが文字列内の単語数を超える場合にのみ、ゼロの位置または長さを返します。返された位置がゼロ以下の場合、ループを停止できます。ループを終了するには、エラーによって位置が欠損する場合に備えて、ゼロに対する厳密な等価比較を使用するかわりに不等比較を使用するほうが安全です。(SASでは、欠損値は非欠損値より値が小さいとみなされます)。
data all;
   length word $20;
   drop string;
   string=' The quick brown fox jumps over the lazy dog.   ';
   do until(position <= 0);
      count+1;
      call scan(string, count, position, length);
      word=substrn(string, position, length);
      output;
   end;
run;
proc print data=all noobs;
   var count position length word;
run;
M修飾子を使用しない文字列内のすべての単語の検索結果出力
M修飾子を使用しない文字列内のすべての単語の検索結果出力

例4: M修飾子とO修飾子を使用して文字列内のすべての単語を検索する

区切り文字としてカンマを指定したM修飾子を使用した結果の例を次に示します。M修飾子を使用すると、先頭、末尾および複数の連続する区切り文字がある場合、CALL SCANルーチンは長さがゼロの単語を返します。
区切り文字と修飾子はCALL SCANルーチンのすべての呼び出しで同じであるため、効率を上げるためにO修飾子を使用します。
data comma;
   length word $30;
   string=',leading,  trailing,and multiple,,delimiters, ,';
   do until(position <= 0);
      count + 1;
      call scan(string, count, position, length, ', ', 'mo');
      word=substrn(string, position, length);
      output;
   end;
run;
proc print data=comma noobs;
   var count position length word;
run;   
M修飾子とO修飾子を使用した文字列内のすべての単語の検索結果出力
M修飾子とO修飾子を使用した文字列内のすべての単語の検索結果出力

例5: カンマ区切り値、引用符内の部分文字列およびO修飾子を使用する

O修飾子と区切り文字としてカンマを指定したCALL SCANルーチンを使用する例を次に示します。
CALL SCANルーチンの各呼び出しでは区切り文字と修飾子は変わらないため、効率を上げるためにO修飾子を使用します。
data test;
   length word word_r $30;
   string='He said, "She said, ""No!""", not "Yes!"';
   do until(position <= 0);
      count + 1;
      call scan(string, count, position, length, ', ', 'oq');
      word=substrn(string, position, length);
      output;
   end;
run;
proc print data=test noobs;
   var count position length word;
run;
カンマ区切り値と引用符内の部分文字列の出力結果
カンマ区切り値と引用符内の部分文字列の出力結果

例6: D修飾子とK修飾子を使用して数字の部分文字列を検索する

数字の部分文字列を検索する例を次に示します。character-list引数がNULLであるため、文字のリストは最初は空になります。D修飾子は文字のリストに数字を追加します。K修飾子はリストに含まれていない文字をすべて区切り文字として扱います。したがって、数字以外の文字はすべて区切り文字になります。
data digits;
   length digits $20;
   string='Call (800) 555–1234 now!';
   do until(position <= 0);
      count+1;
      call scan(string, count, position, length, , 'dko');
      digits=substrn(string, position, length);
      output;
   end;
run;
proc print data=digits noobs;
   var count position length digits;
run;
D修飾子とK修飾子を使用した数字の部分文字列の検索結果出力
D修飾子とK修飾子を使用した数字の部分文字列の検索結果出力

関連項目:

前のページ|次のページ|ページの先頭へ