MiddleIndexOf
両方IndexOf
ではなくLastIndexOf
、検索を開始するポイントを選択できます。
例えば:
string str = @"1\2\3\4\5";
// indexes: 012345678
int index = str.IndexOf('\\', 4);
// index = 5, it starts searching from: "3\4\5"
2 番目のスラッシュのインデックスを取得するには、次のようにします。
string str = @"1\2\3\4\5";
int index = str.IndexOf('\\', str.IndexOf('\\') + 1);
最後から 2 番目のスラッシュを取得するコードは次のとおりです。
string str = @"1\2\3\4\5";
int index = str.LastIndexOf('\\', str.LastIndexOf('\\') - 1);
文字列内の文字のすべてのインデックスを一覧表示するには、次の拡張メソッドが役立ちます。
public static int[] GetAllIndexes(this string @this, string substr)
{
var indexes = new List<int>();
int index = -1;
while ((index = @this.IndexOf('\\', index + 1)) >= 0) indexes.Add(index);
return indexes.ToArray();
}
public static int[] GetAllIndexes(this string @this, char substr)
{
var indexes = new List<int>();
int index = -1;
while ((index = @this.IndexOf('\\', index + 1)) >= 0) indexes.Add(index);
return indexes.ToArray();
}
次のように使用できます。
string str = @"1\2\3\4\5";
int[] indexes = str.GetAllIndexes('\\');
説明したBeforeLastIndexOf
関数は次のようになります。
public static int BeforeLastIndexOf(this string @this, string substr, int beforeCount)
{
int index = @this.LastIndexOf(substr, @this.Length - 1);
for (int i = 0; i < beforeCount && index >= 0; i++)
index = @this.LastIndexOf(substr, index - 1);
return index;
}
public static int BeforeLastIndexOf(this string @this, char substr, int beforeCount)
{
int index = @this.LastIndexOf(substr, @this.Length - 1);
for (int i = 0; i < beforeCount && index >= 0; i++)
index = @this.LastIndexOf(substr, index - 1);
return index;
}
次のように使用します。
string str = @"1\2\3\4\5";
// indexes: 0123456789
int index = str.BeforeLastIndexOf('\\', 2);
最後のインデックスの前に 2 つのインデックスを返します。この場合、3 が返されます (\5 が最後、\4、\3、\3 の前の \ のインデックスは 3)。
あなたは同じことをしIndexOf
て作ることができますAfterIndexOf
:
public static int AfterIndexOf(this string @this, string substr, int afterCount)
{
int index = @this.IndexOf(substr);
for (int i = 0; i < afterCount && index >= 0; i++)
index = @this.IndexOf(substr, index + 1);
return index;
}
public static int AfterIndexOf(this string @this, char substr, int afterCount)
{
int index = @this.IndexOf(substr);
for (int i = 0; i < afterCount && index >= 0; i++)
index = @this.IndexOf(substr, index + 1);
return index;
}
次のように使用できます。
string str = @"1\2\3\4\5";
// indexes: 0123456789
int index = str.AfterIndexOf('\\', 2);
これは、4 の前の \ である 5 を返します。
実際に MiddleIndexOf を取得するには、つまり中央に最も近いインデックスを取得するには、次の拡張メソッドを使用できます。
public static int MiddleIndexOf(this string @this, string substr, bool roundUp = false, bool preferUp = true)
{
// Determine the middle character
int middlePoint = (roundUp ? @this.Length : @this.Length - 1) / 2;
// Find the indexes closest to the middle
int indexBelow = @this.LastIndexOf(substr, middlePoint);
int indexAbove = @this.IndexOf(substr, middlePoint);
if (indexBelow < 0) return indexAbove;
if (indexAbove < 0) return indexBelow;
int diffBelow = middlePoint - indexBelow;
int diffAbove = indexAbove - middlePoint;
return diffAbove == diffBelow ? (preferUp ? indexAbove : indexBelow) : // If it's the same difference
(diffAbove < diffBelow ? indexAbove : indexBelow); // Otherwise return the closest index
}
public static int MiddleIndexOf(this string @this, char substr, bool roundUp = false, bool preferUp = true)
{
// Determine the middle character
int middlePoint = (roundUp ? @this.Length : @this.Length - 1) / 2;
// Find the indexes closest to the middle
int indexBelow = @this.LastIndexOf(substr, middlePoint);
int indexAbove = @this.IndexOf(substr, middlePoint);
if (indexBelow < 0) return indexAbove;
if (indexAbove < 0) return indexBelow;
int diffBelow = middlePoint - indexBelow;
int diffAbove = indexAbove - middlePoint;
return diffAbove == diffBelow ? (preferUp ? indexAbove : indexBelow) : // If it's the same difference
(diffAbove < diffBelow ? indexAbove : indexBelow); // Otherwise return the closest index
}
次のように使用できます。
string str = @"1\2\3\4\5\";
int index = str.MiddleIndexOf('\\');
オプションのパラメータが 2 つあります。
roundUp
: true に設定されていて、文字数が偶数の場合は切り上げられ、それ以外の場合は切り捨てられます。たとえば、8 文字の場合: roundUp が false の場合は中間点として"12345678"
選択され、そうでない場合は.4
5
preferUp
: 文字列の後半に、文字列の前半と同じだけ中間点から離れた文字がある場合、どちらを選択するかが決まります。デフォルトではtrue
、切り捨てを補正するように設定されています。(8 文字"\1\2\3\4"
の文字列がある場合、中間点は 3.5 にあるはずですが、これが不可能なため、インデックス 3 から検索します。インデックス 3 は'2'
、\
上記と同じくらい下にあります。しかし、これが真であるためです。の場合、中間点から 0.5 離れたインデックス 4 の文字が選択されます。そうでない場合は1.5
、実際の中間点から遠く離れた下のインデックスが選択されます。)