0

我知道如何使用字符串的方法IndexOfLastIndexOf. 但是我想知道是否有可能以某种“MiddleIndexOf”的“短途”方式进行,所以介于IndexOf和之间LastIndexOf

告诉你我的意思,最好的方法是展示一个例子:

string str = @"1\2\3\4\5";

从 4 开始(所以“4\5”)如何获得部分上部字符串。这意味着我不能使用 IndexOf 或 LastIndexOf,但我需要类似“BeforeLastIndexOf”方法。

或者不仅如此,假设我想要从 3 开始的部分字符串(所以“3\4\5”)。这甚至意味着我不能使用“BeforeLastIndexOf”,而是使用不同的东西。

--

这意味着:LastIndexOf 之前 1,或 LastIndexOf 之前 2(或者可能从前面:IndexOf 之后 2,或 IndexOf 之后 3)。

--

我知道我可以通过反斜杠分隔符拆分字符串,但我想知道是否有任何方法可以使用字符串方法(如解释的那样)。

提前致谢,

再见

4

3 回答 3

3

没有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"

要获取第二个斜杠的索引,您需要执行以下操作:

string str = @"1\2\3\4\5";
int index = str.IndexOf('\\', str.IndexOf('\\') + 1);

要获得倒数第二个斜杠,代码如下:

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);

这又返回 5,即 4 之前的 \。


要真正获得 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('\\');

有两个可选参数:

  • roundUp: 如果它设置为 true,并且你有偶数个字符,它会向上取整,否则它会向下取整。例如,如果您有 8 个字符:如果 roundUp 为 false,"12345678"它将选择作为中间点,否则.45
  • preferUp:当字符串后面的中间点与字符串前面的字符一样多的字符时,这将确定它选择哪个字符。默认情况下,它设置为true补偿向下舍入。(如果你有一个 8 个字符"\1\2\3\4"的字符串,中间点应该是 3.5,但是因为这是不可能的,所以它会从索引 3 开始搜索。索引 3与上面一样远。但由于这是'2'真的\,它会选择索引 4 处距离中点 0.5 远的字符,否则它会选择下面的索引,这将1.5远离真正的中点。)
于 2012-09-27T16:53:44.363 回答
1

您可以提供一个起点String.IndexOf(string, Int32)。如果结果索引超出您的“终点”,则两者之间不存在任何内容。

例如,给定您的字符串:

string str = @"1\2\3\4\5";

如果您想限制@"4\5"并找到斜线的索引:

int index = str.IndexOf(@"\", 6); // Start at char 6, returns 7
于 2012-09-27T16:53:35.467 回答
0

如果您知道第一个字符的索引,则可以使用在第一个字符string.IndexOf(value, startIndex)之后开始搜索下一个实例。

此代码将获取第二个字符的索引:

public int static SecondIndexOf(this string str, char value)
{
    var firstIndex = str.IndexOf(char);
    if (firstIndex == -1)
        return firstIndex;

    return str.IndexOf(char, firstIndex + 1);
}
于 2012-09-27T16:54:04.230 回答