LastIndexOfによる文字列検索で、指定した文字数より手前の文字列を検索する

string オブジェクトの LastIndexOf メソッドで指定した文字列以前を検索するコードを紹介します。

概要

文字列を後方から検索する - LastIndexOf による文字列検索」では、LastIndexOfメソッドを用いて文字列を後方から検索するコードを紹介しましたが、検索処理は常に文字列の最後から開始されるため、文字列内に複数の検索にヒットする場所があった場合でも(文字列の末尾から見て)最初の該当位置しか返されません。この記事では指定した文字列インデックス以前を検索対象にすることで、複数の該当場所を取得できるようにします。

書式

LastIndexOfで指定した文字列以降の文字を検索対象にする場合は、LastIndexOfの第二引数に検索を開始する位置のインデックス番号(文字位置)を与えます。

プログラム

UI

下図のUIを作成します。。こちらの記事で作成したフォームにボタンを一つ追加したものです。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SearchString
{
  public partial class FormSearchPrev : Form
  {
    int pos = -1;

    public FormSearchPrev()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      string text = textBox_Text.Text;
      string search = textBox_Search.Text;

      pos = text.LastIndexOf(search);
      textBox_Output.Text += string.Format("{0:d} 文字目で該当しました。\r\n", pos);
    }

    private void button2_Click(object sender, EventArgs e)
    {
      string text = textBox_Text.Text;
      string search = textBox_Search.Text;

      pos = text.LastIndexOf(search,pos);
      textBox_Output.Text += string.Format("{0:d} 文字目で該当しました。\r\n", pos);
    }
  }
}

解説

  int pos = -1;
検索結果を保存するため、クラスのメンバ変数としてposを定義します。

private void button1_Click(object sender, EventArgs e)
{
  string text = textBox_Text.Text;
  string search = textBox_Search.Text;

  pos = text.LastIndexOf(search);
  textBox_Output.Text += string.Format("{0:d} 文字目で該当しました。\r\n", pos);
}
Button1は検索対象文字列の末尾から検索するロジックです。詳しくはこちらの記事を参照してください。

private void button2_Click(object sender, EventArgs e)
{
  string text = textBox_Text.Text;
  string search = textBox_Search.Text;

  pos = text.LastIndexOf(search,pos);
  textBox_Output.Text += string.Format("{0:d} 文字目で該当しました。\r\n", pos);
}
button2は前回の検索結果より手前の文字列を検索するロジックです。LastIndexOfの第二引数に前回の検索結果であるpos変数与えることで、前回マッチした文字以前の文字列に対して検索を実行できます。

実行結果

プロジェクトを実行します。下図のフォームが表示されます。


テキストボックスに入力します。今回は以下の文字列を入力しました。
  • 検索対象文字列 : リンゴとみかんを購入してリンゴを食べたらリンゴが無くなった
  • 検索文字列 : リンゴ


[Search]ボタンをクリックします。検索対象文字列の末尾から検索が実行され、最初にマッチしたインデックスの20(21文字目)が結果として返されます。


続いて[Search Dec]ボタンをクリックします。先の検索結果の手前の文字列に対して検索処理が実行され、12が結果で返されます。


[Search Dec]ボタンをクリックするごとに手前に向かって検索します。


検索にヒットしない場合は、-1を返します。

補足

検索文字列が一部含まれる位置から検索を開始した場合
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SearchString
{
  public partial class FormSpecialCase : Form
  {
    public FormSpecialCase()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      string text = "C#の世界へようこそ";
      string search = "世界へ";

      int pos = text.LastIndexOf(search, 4);
      textBox1.Text += string.Format("{0:d} 文字目で該当しました。\r\n", pos);
    }
  }
}
上記のコードのように、 検索文字列の一部が含まれる位置をLastIndexOfの第二引数に与えた場合は、検索にマッチしない結果となります。



検索文字列がすべて含まれる位置から検索を開始した場合
private void button1_Click(object sender, EventArgs e)
{
  string text = "C#の世界へようこそ";
  string search = "世界へ";

  int pos = text.LastIndexOf(search, 6);
  textBox1.Text += string.Format("{0:d} 文字目で該当しました。\r\n", pos);
}
検索文字列のすべてが含まれる位置をLastIndexOfの第二引数に与えると、検索にマッチします。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2015-01-22
iPentec all rights reserverd.