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

时间:2010-03-30 20:14:57

标签: c# regex

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

StringParser.GetSubstrings("[start]aaaaaa[end] wwwww [start]cccccc[end]", "[start]", "[end]");

返回2个字符串“aaaaaa”和“cccccc” 假设我们只有一个嵌套级别。 不确定regexp,但我认为它会有用。

6 个答案:

答案 0 :(得分:33)

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

答案 1 :(得分:5)

这是一个不使用正则表达式且不考虑嵌套的解决方案。

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

答案 2 :(得分:2)

您需要更好地定义管理匹配需求的规则。在构建任何类型的匹配或搜索代码时,您需要清楚地了解您预期的输入和输出你需要生产。如果不仔细考虑这些问题,那么生成错误代码非常容易。那说......

您应该能够使用正则表达式。嵌套可能会使它稍微复杂但仍然可行(取决于您希望在嵌套方案中匹配的内容)。应该让你开始:

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

将上面的代码包装到适合您需要的函数中应该是微不足道的。

答案 3 :(得分:2)

您可以使用正则表达式,但请记住在您的参数上调用Regex.Escape

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

我还添加了SingleLine选项,即使文字中有新行也会匹配。

答案 4 :(得分:0)

我很无聊,因此我做了一个无用的微基准测试,“证明”(在我的数据集上,其中包含最多7k个字符串和<b>标记用于开始/结束参数)我怀疑 juharr 的解决方案是三个整体中最快的。

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

juharr: 6371ms
Jake: 6825ms
Mark Byers: 82063ms

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

答案 5 :(得分:0)

无正则表达法:

public static List<string> extract_strings(string src, string start, string end)
{
    if (src.IndexOf(start) > 0)
    {
        src = src.Substring(src.IndexOf(start));
    }
    string[] array1 = src.Split(new[] { start }, StringSplitOptions.None);
    List<string> list = new List<string>();
    foreach (string value in array1)
    {
        if (value.Contains(end))
        {
            list.Add(value.Split(new[] { end }, StringSplitOptions.None)[0]);
        }
    }
    return list;
}