字符串方法,如Middle IndexOf - 它可以完成吗?

时间:2012-09-27 16:51:25

标签: c# string

我知道如何使用字符串的方法IndexOfLastIndexOf。但是我想知道是否可以某种方式使用某种“MiddleIndexOf”进行“短路”,所以IndexOfLastIndexOf之间存在某种关系。

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

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

-

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

提前大事,

再见

3 个答案:

答案 0 :(得分:3)

没有MiddleIndexOf,但IndexOfLastIndexOf都允许您选择开始搜索的点。

例如:

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个字符:"12345678"如果roundUp为false,则会选择4作为中间点,否则为5
  • preferUp:如果字符串中的某个字符与字符串中较早的中间点一样多,那么它将决定选择哪一个字符。默认情况下,它设置为true以补偿向下舍入。 (如果你有一个8个字符的字符串"\1\2\3\4",那么中间点应该是3.5,但由于这是不可能的,它将从索引3中搜索。索引3是'2'一个\如上所述,但是由于这是真的,它会选择指数4处的字符,距离中点0.5远,否则选择下面的指数,即1.5远离真正的中点。)

答案 1 :(得分: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

答案 2 :(得分: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);
}