2005年07月26日

文字列から文字要素(トークン)を取得する方法

検索エンジンのキーワード欄に入力された文字列や、
CSVファイルのようなカンマ、タブで区切られた文字列から、
各文字要素(トークン)を取得する方法をDelphiで紹介します。


私が大学生だった頃、
AI(人工知能)なる言葉やLISP言語が流行していました。
このAIの研究に没頭されていた教授から、
夏休みにインタープリタをつくりなさいという課題を与えられ、
面白半分、悩み半分で取組んだ思い出があります。

今回ご紹介する関数は、
CVSファイルの文字列トークン取得から、
文脈自由型のコンパイラやインタープリタの文脈解析まで、
幅広い問題の解決にご利用いただけるかと思います。
また、このアルゴリスムは
初級情報処理技術者資格試験にも
出題されるたことがありますよ。


ではさっそく、プログラムを紹介しましょうね。

_GetTokenソースは【続きを読む】をクリック!

関数仕様
function _GetToken(
 var pSource: String; pDelimiter: String): String;
説明
pSourceで指定された文字列から、pDelimiterで指定された区切り文字こどに文字列要素を取り出し戻します。文字列要素を取り出した後、入力されたpSourceは、始めに見つかった区切り文字以降の文字列に再編集されます。pSourceで指定された文字列から文字列要素を取り出せない場合、関数は空の文字列を戻します。pDelmiterには区切り文字を複数指定できます。
使用例
procedure TForm1.Button1Click(Sender: TObject);
var
 lText,
 lToken: String;
begin
 // 'Hello, This is guy.'の文字列から' ,.'を区切り文字とし、
 // 'Hello','This','is','guy'の各文字トークンを取得する。

 lText := 'Hollo, This is guy.';
 while (lText <> '') do
 begin
  lToken := _GetToken(lText, ' ,.');
  if (lToken = '') then
   Break;
  Memo1.Lines.Add(lToken);
 end;
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

注意:
 下記ソースファイルは、本ページの管理者である「guy」が個人的に作成しました。
 このソースは作者に断り無く、個人がコピー、改造することは許可しますが、
 いかなる場合であっても、商用目的に使用することを固く禁じます。
 あと、ホームページでの公開の都合上、各ソースの先頭に全角スペースが入ってます。
 あなたがDelphiでコンパイルする前に、この全角スペースを半角スペースに変換してくださいね。

Source: _GetToken
function _GetToken(var pSource: String; pDelimiter: String): String;
 //----------------------------------------------------------------------------
 function IsDelimiter(pSource, pDelimiter: String): Boolean;
 var
  lCnt: Integer;
 begin
  Result := False;
  for lCnt := 0 to Length(pDelimiter) do
  begin
   if (pSource = Copy(pDelimiter, lCnt, 1)) then
   begin
    Result := True;
    Break;
   end;
  end;
 end;
var
 lCnt,
 lPos: Integer;
 lStr,
 lChr: String;
 lFlg: Boolean;
begin
 Result := '';
 lStr := pSource + Copy(pDelimiter, 1, 1);
 lFlg := False;
 for lCnt := 1 to Length(lStr) do
 begin
  lChr := Copy(lStr, lCnt, 1);
  // 区切り文字を検索し文字開始位置を記憶している場合、
  // 区切り文字までの文字列トークンを関数の戻り値に設定し、
  // 入力文字列を検索した区切り文字移行の文字列に調整する
  if (IsDelimiter(lChr, pDelimiter)) then
  begin
   if (lFlg) then
   begin
    Result := Copy(lStr, lPos, lCnt-lPos);
    pSource := Copy(pSource, lCnt+1, Length(pSource));
    Exit;
   end;
  end
  else
  // 区切り文字でない場合、文字開始位置を記憶する
  begin
   if (not lFlg) then
   begin
    lPos := lCnt;
    lFlg := True;
   end;
  end;
 end;
 pSource := Copy(pSource, lCnt+1, Length(pSource));
end;
posted by guy at 08:38 | 文字列操作編
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。