はじめてのDelphi(その5−2)

戻る

ここでは、VBC++BuilderDelphiの文字列操作の違いを見てみます。
文字列操作は言語により記述が大きく異なるので注意が必要です。

文字操作例2

  • 文字列の検索
  • 文字列の置換

 


VBの場合

  • 文字列を置換する機能がないため、ReplaceString() を自作し追加しています。
  • 検索は InStr() を使用しています。この関数はバイナリモードとテキストモードで動作が異なるので注意が必要です。
  • ReplaceString() で使用している ByRef:参照渡し、ByVal:値渡し に注意してください。VBの既定値は ByRef です。
    詳しくはヘルプを参照してください。

先頭へ


Private Sub Command1_Click()
    Dim iwork As Integer    '位置計算用
    Dim swork As String     '検索・置換対象文字列
    Dim search As String    '検索文字列
    Dim change As String    '置換文字列
    Dim msg As String
    
    ' Ex.6: 検索
    swork = "ABCあいうDEFえおか"        ' 検索対象となる文字列式
    
    msg = "検索対象文字列=" + swork + vbCrLf + vbCrLf
    ' テキストモードの検索
    search = "A"
    iwork = InStr(1, swork, search, vbTextCompare)  '見つけた(iwork = 1)
    msg = msg + "A 検索位置=" + Str(iwork) + vbCrLf
    ' バイナリモードの検索
    search = "def"
    iwork = InStr(1, swork, search, vbBinaryCompare)  'バイナリモード時は見つからない(iwork = 0)
    msg = msg + "def 検索位置1=" + Str(iwork) + vbCrLf
    ' テキストモードの検索
    search = "def"
    iwork = InStr(1, swork, search, vbTextCompare)  ' テキストモード時は見つけた(iwork=7)
    msg = msg + "def 検索位置2=" + Str(iwork) + vbCrLf
    ' テキストモードの検索
    search = "DEF"
    iwork = InStr(1, swork, search, vbTextCompare)  ' 見つけた(iwork=7)
    msg = msg + "DEF 検索位置=" + Str(iwork) + vbCrLf
    ' テキストモードの検索
    search = "あいう"
    iwork = InStr(1, swork, search, vbTextCompare)  ' 見つけた(iwork=4)
    msg = msg + "あいう 検索位置=" + Str(iwork) + vbCrLf
    ' テキストモードの検索
    search = "あう"
    iwork = InStr(1, swork, search, vbTextCompare)  ' 見つけた(iwork=0)
    msg = msg + "あう 検索位置=" + Str(iwork)
    
    Call MsgBox(msg)
    
    
    ' Ex.7: 置換
    swork = "ABCあいうDEFえおか"        ' 置換対象となる文字列式
    
    msg = "置換対象文字列=" + swork + vbCrLf + vbCrLf
    ' 置換:AB→ab
    search = "AB"      ' 検索文字列
    change = "ab"   ' 置換文字列
    Call ReplaceString(swork, search, change)  ' 置換結果作成
    msg = msg + "AB→ab 置換後=" + swork + vbCrLf
    ' 置換:DEF→DEF
    search = "DEF"      ' 検索文字列
    change = "DEF"   ' 置換文字列
    Call ReplaceString(swork, search, change)  ' 置換結果作成
    msg = msg + "DEF→DEF 置換後=" + swork + vbCrLf
    ' 置換:あいう→アイウ
    search = "あいう"   ' 検索文字列
    change = "アイウ"   ' 置換文字列
    Call ReplaceString(swork, search, change)  ' 置換結果作成
    msg = msg + "あいう→アイウ 置換後=" + swork + vbCrLf
    ' 置換:か→ka
    search = "か"   ' 検索文字列
    change = "ka"   ' 置換文字列
    Call ReplaceString(swork, search, change)  ' 置換結果作成
    msg = msg + "か→ka 置換後=" + swork + vbCrLf
    ' 置換:は→ハ (この文字は存在しないので無変換)
    search = "は"   ' 検索文字列
    change = "ハ"   ' 置換文字列
    Call ReplaceString(swork, search, change)  ' 置換結果作成
    msg = msg + "は→ハ 置換後=" + swork
    
    Call MsgBox(msg)  ' 変換結果は"abCアイウDEFえおka"
    
End Sub


Private Function ReplaceString(ByRef source As String, ByVal search As String, ByVal change As String) As Boolean
'* 文字列の置換
'* [in]
'*    source : 置換対象文字列
'*    search : 置換元文字列
'*    change : 置換先文字列
'* [out]
'*    置換結果(True:sourceは置換された結果がセットされる)
'* [注意]
'*   置換対象文字列に検索文字列が存在しない場合、文字列をそのまま返します。
'*   英字の大文字、小文字は別文字列としてあつかいます。
'* ( InStr() で vbTextCompare にすれば、大小文字を同一視することができます)
    Dim fwork As String      '検索文字列より前の文字列
    Dim bwork As String      '検索文字列より後ろの文字列
    Dim chgPos As Integer    '検索文字列の位置
    Dim srcLen As Integer    '置換対象文字列の長さ
    Dim srhLen As Integer    '検索文字列の長さ
    Dim fSize As Integer     '検索文字列より前の文字数
    Dim bSize As Integer     '検索文字列より後ろの文字数
    
    chgPos = InStr(1, source, search, vbBinaryCompare)
    If chgPos = 0 Then
        ' 置換対象文字列内に検索文字列が見つからない
        ReplaceString = False
        Exit Function
    End If
    
    srcLen = Len(source)
    srhLen = Len(search)
    ' 検索文字列より前の文字列を切り出す
    fSize = chgPos - 1
    fwork = Left(source, fSize)
    ' 検索文字列より後ろの文字列を切り出す
    bSize = srcLen - chgPos - srhLen + 1
    bwork = Right(source, bSize)
    ' 置換結果を作成
    source = fwork + change + bwork
    
    ReplaceString = True  ' 正常時
End Function


C++Builderの場合

  • 文字列を置換する機能がないため、ReplaceString() を自作し追加しています。
  • 検索は AnsiString::Pos() を使用しています。この関数は大小文字を別文字列として扱うため注意が必要です。
  • ReplaceString() で使用している AnsiString& source のは参照演算子です。この記述で参照渡しができます。
    詳しくはヘルプの「参照引数」を参照してください。

先頭へ

Unit1.h
 private:とpublic:の間に3行追加してください。


private:        // ユーザー宣言
    bool  ReplaceString( AnsiString& source,
                         AnsiString search,
                         AnsiString change );
public:         // ユーザー宣言

Unit1.cpp


//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int    iwork;      // 位置用
  AnsiString swork;  // 検索・置換対象文字列
  AnsiString lwork;  // 検索・置換対象文字列:変換ワーク
  AnsiString search; // 検索文字列
  AnsiString change; // 置換文字列
  AnsiString msg;

  // Ex.6: 検索
  //   AnsiString::Pos() は先頭の文字位置が1なのに注意!
  swork = "ABCあいうDEFえおか";

  msg = "検索対象文字列=" + swork + "\n\n";
  // 検索(英大文字)
  search = "A";
  iwork = swork.Pos( search );  // 見つけた(iwork == 1)
  msg = msg + "A 検索位置=" + IntToStr( iwork ) + "\n";
  // 検索(英小文字)
  search = "def";
  iwork = swork.Pos( search );  // 小文字は見つからない(iwork == 0)
  msg = msg + "def 検索位置=" + IntToStr( iwork ) + "\n";
  // 検索(英大文字)
  search = "DEF";
  iwork = swork.Pos( search );  // 見つけた(iwork == 10)
  msg = msg + "DEF 検索位置=" + IntToStr( iwork ) + "\n";
  // 検索(英小文字):LowerCase を使用
  search = LowerCase( "def" );  // 検索文字列を小文字に変換しておく
  lwork = swork.LowerCase();    // 検索元の文字列を小文字に変換しておく
  iwork = lwork.Pos( search );  // 見つけた(iwork == 10)
  msg = msg + "def 検索位置2=" + IntToStr( iwork ) + "\n";
  // 検索(DBCS:2バイト文字)
  search = "あいう";
  iwork = swork.Pos( search );  // 見つけた(iwork == 4)
  msg = msg + "あいう 検索位置=" + IntToStr( iwork ) + "\n";
  // 検索(DBCS:2バイト文字):存在しない文字
  search = "あう";
  iwork = swork.Pos( search );  // 見つからない(iwork == 0)
  msg = msg + "あう 検索位置=" + IntToStr( iwork );

  ShowMessage( msg );


  // Ex.7: 置換
  swork = "ABCあいうDEFえおか";

  msg = "置換対象文字列=" + swork + "\n\n";
  // 置換:AB→ab
  search = "AB";   // 検索文字列
  change = "ab";   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg = msg + "AB→ab 置換後=" + swork + "\n";
  // 置換:DEF→DEF
  search = "DEF";      // 検索文字列
  change = "DEF";   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg = msg + "DEF→DEF 置換後=" + swork + "\n";
  // 置換:あいう→アイウ
  search = "あいう";   // 検索文字列
  change = "アイウ";   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg = msg + "あいう→アイウ 置換後=" + swork + "\n";
  // 置換:か→ka
  search = "か";   // 検索文字列
  change = "ka";   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg = msg + "か→ka 置換後=" + swork + "\n";
  // 置換:は→ハ (この文字は存在しないので無変換)
  search = "は";   // 検索文字列
  change = "ハ";   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg = msg + "は→ハ 置換後=" + swork;

  ShowMessage( msg );  // 変換結果は"abCアイウDEFえおka"

}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// ReplaceString()
//   AnsiString 内の指定された文字列を置換します
// [in]
//   source : 置換対象文字列(AnsiString のみ)
//   search : 検索文字列
//   change : 置換文字列
// [out]
//   置換結果(== true:sourceは置換された結果がセットされる)
// [注意]
//   置換対象文字列に検索文字列が存在しない場合、文字列をそのまま
//   返します。
//   英字の大文字、小文字は別文字列としてあつかいます。
//
bool  TForm1::ReplaceString( AnsiString& source,
                             AnsiString search,
                             AnsiString change )
{
  AnsiString  fwork;  // 検索文字列より前の文字列
  AnsiString  bwork;  // 検索文字列より後ろの文字列
  int  chgPos;  // 検索文字列の位置
  int  srcLen;  // 置換対象文字列の長さ
  int  srhLen;  // 検索文字列の長さ
  int  fSize;   // 検索文字列より前の文字数
  int  bSize;   // 検索文字列より後ろの文字数

  chgPos = source.Pos( search );
  if( chgPos == 0 ){
    // 置換対象文字列内に検索文字列が見つからない
    return false;
  }

  srcLen = source.Length();
  srhLen = search.Length();
  // 検索文字列より前の文字列を切り出す
  fSize = chgPos - 1;
  fwork = source.SubString( 1, fSize );
  // 検索文字列より後ろの文字列を切り出す
  bSize = srcLen - ( chgPos + srhLen - 1 );
  bwork = source.SubString( ( chgPos + srhLen ), bSize );
  // 置換結果を作成
  source = fwork + change + bwork;

  return true;  // 正常時
}
//---------------------------------------------------------------------------


Delphiの場合

  • 文字列を置換する機能がないため、ReplaceString() を自作し追加しています。
  • 検索は Pos() を使用しています。この関数は大小文字を別文字列として扱うため注意が必要です。
  • ReplaceString() で使用している var source: AnsiString;var は変数パラメータです。この記述で参照渡しができます。
    詳しくはヘルプの「パラメータの受け渡し」を参照してください。

先頭へ

Unit1.pas


type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    Function ReplaceString( var source: AnsiString; search, change: AnsiString ): Boolean;
  public
    { Public 宣言 }
  end;


procedure TForm1.Button1Click(Sender: TObject);
var
  iwork: Integer;     // 位置用
  swork: AnsiString;  // 検索・置換対象文字列
  lwork: AnsiString;  // 検索・置換対象文字列:変換ワーク
  search: AnsiString; // 検索文字列
  change: AnsiString; // 置換文字列
  msg: AnsiString;
begin
  // Ex.6: 検索
  //   AnsiString::Pos() は先頭の文字位置が1なのに注意!
  swork := 'ABCあいうDEFえおか';

  msg := '検索対象文字列=' + swork + #13#13;
  // 検索(英大文字)
  search := 'A';
  iwork := Pos( search, swork );  // 見つけた(iwork = 1)
  msg := msg + 'A 検索位置=' + IntToStr( iwork ) + #13;
  // 検索(英小文字)
  search := 'def';
  iwork := Pos( search, swork );  // 小文字は見つからない(iwork = 0)
  msg := msg + 'def 検索位置=' + IntToStr( iwork ) + #13;
  // 検索(英大文字)
  search := 'DEF';
  iwork := Pos( search, swork );  // 見つけた(iwork = 10)
  msg := msg + 'DEF 検索位置=' + IntToStr( iwork ) + #13;
  // 検索(英小文字):LowerCase を使用
  search := LowerCase( 'def' );  // 検索文字列を小文字に変換しておく
  lwork := LowerCase( swork );   // 検索元の文字列を小文字に変換しておく
  iwork := Pos( search, lwork ); // 見つけた(iwork = 10)
  msg := msg + 'def 検索位置2=' + IntToStr( iwork ) + #13;
  // 検索(DBCS:2バイト文字)
  search := 'あいう';
  iwork := Pos( search, swork );  // 見つけた(iwork = 4)
  msg := msg + 'あいう 検索位置=' + IntToStr( iwork ) + #13;
  // 検索(DBCS:2バイト文字):存在しない文字
  search := 'あう';
  iwork := Pos( search, swork );  // 見つからない(iwork = 0)
  msg := msg + 'あう 検索位置=' + IntToStr( iwork );

  ShowMessage( msg );


  // Ex.7: 置換
  swork := 'ABCあいうDEFえおか';

  msg := '置換対象文字列=' + swork + #13#13;
  // 置換:AB→ab
  search := 'AB';   // 検索文字列
  change := 'ab';   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg := msg + 'AB→ab 置換後=' + swork + #13;
  // 置換:DEF→DEF
  search := 'DEF';      // 検索文字列
  change := 'DEF';   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg := msg + 'DEF→DEF 置換後=' + swork + #13;
  // 置換:あいう→アイウ
  search := 'あいう';   // 検索文字列
  change := 'アイウ';   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg := msg + 'あいう→アイウ 置換後=' + swork + #13;
  // 置換:か→ka
  search := 'か';   // 検索文字列
  change := 'ka';   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg := msg + 'か→ka 置換後=' + swork + #13;
  // 置換:は→ハ (この文字は存在しないので無変換)
  search := 'は';   // 検索文字列
  change := 'ハ';   // 置換文字列
  ReplaceString(swork, search, change);  // 置換結果作成
  msg := msg + 'は→ハ 置換後=' + swork;

  ShowMessage( msg );  // 変換結果は"abCアイウDEFえおka"

end;


//---------------------------------------------------------------------------
// ReplaceString()
//   AnsiString 内の指定された文字列を置換します
// [in]
//   source : 置換対象文字列(AnsiString のみ)
//   search : 検索文字列
//   change : 置換文字列
// [out]
//   置換結果(= true:sourceは置換された結果がセットされる)
// [注意]
//   置換対象文字列に検索文字列が存在しない場合、文字列をそのまま
//   返します。
//   英字の大文字、小文字は別文字列としてあつかいます。
//   ( ReplaceString() 内の var はVBの ByRef や C++ の 参照渡し
//   と同じです。)
//
Function TForm1.ReplaceString( var source: AnsiString; search, change: AnsiString ): Boolean;
var
  fwork: AnsiString;  // 検索文字列より前の文字列
  bwork: AnsiString;  // 検索文字列より後ろの文字列
  chgPos: Integer;    // 検索文字列の位置
  srcLen: Integer;    // 置換対象文字列の長さ
  srhLen: Integer;    // 検索文字列の長さ
  fSize: Integer;     // 検索文字列より前の文字数
  bSize: Integer;     // 検索文字列より後ろの文字数
begin
  chgPos := Pos( search, source );
  if chgPos = 0 then
  begin
    // 置換対象文字列内に検索文字列が見つからない
    Result := false;
    Exit;
  end;

  srcLen := Length( source );
  srhLen := Length( search );
  // 検索文字列より前の文字列を切り出す
  fSize := chgPos - 1;
  fwork := Copy( source, 1, fSize );
  // 検索文字列より後ろの文字列を切り出す
  bSize := srcLen - ( chgPos + srhLen - 1 );
  bwork := Copy( source, ( chgPos + srhLen ), bSize );
  // 置換結果を作成
  source := fwork + change + bwork;

  Result := true;  // 正常時
end;
//---------------------------------------------------------------------------

 

先頭へ/戻る