C# 查找两个字符串之间的所有子字符串

C# 查找两个字符串之间的所有子字符串,c#,regex,C#,Regex,我需要从字符串中获取所有子字符串。 例如: StringParser.GetSubstrings("[start]aaaaaa[end] wwwww [start]cccccc[end]", "[start]", "[end]"); 返回两个字符串“aaaaa”和“cccc” 假设我们只有一个嵌套级别。 不确定是否使用regexp,但我认为它会很有用。私有IEnumerable GetSubstring(字符串输入、字符串开始、字符串结束) private IEnumerable<str

我需要从字符串中获取所有子字符串。
例如:

StringParser.GetSubstrings("[start]aaaaaa[end] wwwww [start]cccccc[end]", "[start]", "[end]");
返回两个字符串“aaaaa”和“cccc” 假设我们只有一个嵌套级别。 不确定是否使用regexp,但我认为它会很有用。

私有IEnumerable GetSubstring(字符串输入、字符串开始、字符串结束)
private IEnumerable<string> GetSubStrings(string input, string start, string end)
{
    Regex r = new Regex(Regex.Escape(start) + "(.*?)" + Regex.Escape(end));
    MatchCollection matches = r.Matches(input);
    foreach (Match match in matches)
        yield return match.Groups[1].Value;
}
{ Regex r=newregex(Regex.Escape(start)+“(.*?”+Regex.Escape(end)); MatchCollection matches=r.matches(输入); foreach(匹配中的匹配) 产生返回匹配。组[1]。值; }
您需要更好地定义管理匹配需求的规则。在构建任何类型的匹配或搜索代码时,您需要清楚地了解您预期的输入和需要生成的输出。如果不仔细考虑这些问题,很容易产生错误代码。也就是说

您应该能够使用正则表达式。嵌套可能会使其稍微复杂一些,但仍然可行(取决于您希望在嵌套场景中匹配的内容)。类似的内容应该让您开始:

var start = "[start]";
var end = "[end]";
var regEx = new Regex(String.Format("{0}(.*){1}", Regex.Escape(start), Regex.Escape(end)));
var source = "[start]aaaaaa[end] wwwww [start]cccccc[end]";
var matches = regEx.Match( source );

将上述代码包装成适合您需要的函数应该很简单。

您可以使用正则表达式,但请记住调用参数:

public static IEnumerable<string> GetSubStrings(
   string text,
   string start,
   string end)
{
    string regex = string.Format("{0}(.*?){1}",
        Regex.Escape(start), 
        Regex.Escape(end));

    return Regex.Matches(text, regex, RegexOptions.Singleline)
        .Cast<Match>()
        .Select(match => match.Groups[1].Value);
}
公共静态IEnumerable GetSubstring(
字符串文本,
字符串开始,
字符串结束)
{
string regex=string.Format(“{0}(.*?{1}”),
Regex.Escape(开始),
Regex.Escape(end));
返回Regex.Matches(text、Regex、RegexOptions.Singleline)
.Cast()
.Select(match=>match.Groups[1].Value);
}

我还添加了这个选项,这样即使文本中有新行,它也会匹配。

这里有一个解决方案,它不使用正则表达式,也不考虑嵌套

public static IEnumerable<string> EnclosedStrings(
    this string s, 
    string begin, 
    string end)
{
    int beginPos = s.IndexOf(begin, 0);
    while (beginPos >= 0)
    {
        int start = beginPos + begin.Length;
        int stop = s.IndexOf(end, start);
        if (stop < 0)
            yield break;
        yield return s.Substring(start, stop - start);
        beginPos = s.IndexOf(begin, stop+end.Length);
    }           
}
公共静态IEnumerable封闭字符串(
这个字符串,
字符串开始,
字符串结束)
{
int beginPos=s.IndexOf(begin,0);
while(beginPos>=0)
{
int start=beginPos+begin.Length;
int stop=s.IndexOf(结束,开始);
如果(停止<0)
屈服断裂;
收益率返回s.子串(开始,停止-开始);
beginPos=s.IndexOf(开始、停止+结束长度);
}           
}

我很无聊,因此我做了一个无用的微基准测试,“证明”(在我的数据集上,有多达7k个字符的字符串和开始/结束参数的标签)我怀疑juharr的解决方案是三个方案中最快的

结果(1000000次迭代*20个测试用例):


注意:在我的数据集上,编译后的正则表达式并没有加快多少速度。

1级嵌套意味着
[start]xxx[start]yyy[end]zzz[end]
是可能的?如果你这样做是为了解析HTML或XML,有更好的方法。。。
juharr: 6371ms
Jake: 6825ms
Mark Byers: 82063ms