查找子字符串的起始索引和结束索引

时间:2018-03-28 17:04:57

标签: c# string

我有一个像" ________ _____________这样的字符串,当一个行为立即被删除一个厌恶的________后,会增加未来的行为频率"

我想返回包含每个下划线区域的第一个和最后一个索引位置的数组或列表。

e.g。在我的例子中,我得到(0,7,9,21,101,108)

6个数字是下划线的三个部分的开始和结束的索引 - 第一个'空白'从索引1开始,到索引7结束,第二个从第9位开始,到第21位结束等。

这是我到目前为止所做的,但我已经卡住了

public List<int> GetPositions(string source, string searchString)
{
    List<int> ret = new List<int>();
    int len = searchString.Length;
    int start = -len;
    while (true)
    {
        start = source.IndexOf(searchString, start + len);
        if (start == -1)
        {
            break;
        }
        else
        {
            ret.Add(start);
        }
    }
    return ret;
}

3 个答案:

答案 0 :(得分:3)

您可以使用简单的正则表达式:

var matches = Regex.Matches(s, "_+");
var result = new List<int>();
foreach(Match m in matches)
{
    result.Add(m.Index);
    result.Add(m.Index + m.Length - 1);
}
Console.WriteLine(String.Join(", ", result));

工作示例:https://dotnetfiddle.net/GX9MXR

如果您想避免在单词中加以强调,您也可以使用@"\b_+\b"

答案 1 :(得分:3)

如果你不喜欢正则表达式,这似乎可以做你想要的事情:

public List<int> GetUnderscorePositions(string source)
{
   List<int> positions = new List<int>();
   bool withinUnderscore = false;

   for (int i = 0; i < source.Length; i++) {
        var c = source[i];
        if (c == '_') {
            if (withinUnderscore) {
                continue;
            }
            else {
                withinUnderscore = true;
                positions.Add(i);
            }
        }
        else if (withinUnderscore) {
            withinUnderscore = false;
            positions.Add(i - 1);   
       }
    }

    return positions;
}

答案 2 :(得分:2)

你可以使用string.IndexOf()的各种重载找到所有这些。

你可以通过以下方式获得第一个“空白”的开头:

sourceString.IndexOf('_');

然后第一个空白的结尾:

sourceString.IndexOf("_ ");

第二个“空白”的开头:

sourceString.IndexOf('_', endBlank1Index + 1);

第二个“空白”的结尾:

sourceString.IndexOf("_ ", startBlank2Index);

冲洗并重复直至找不到其他事件。