查找两个字符串之间的所有子字符串
我需要从字符串中获取所有子字符串。
对于前:
查找两个字符串之间的所有子字符串
StringParser.GetSubstrings("[start]aaaaaa[end] wwwww [start]cccccc[end]", "[start]", "[end]");
返回2串 “AAAAAA” 和 “CCCCCC” 假设我们只有一个级别嵌套。 不知道有关正则表达式,但我认为它将是有用的。
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;
}
确切的我需要什么,谢谢 – 2010-03-30 20:28:05
+1 - 尤其是Regex.Escape :) – 2010-03-30 20:34:35
您将需要更好地定义管理您的匹配需求的规则。在构建任何类型的匹配或搜索代码时,您需要清楚地了解您预期哪些输入以及需要生成哪些输出。如果不仔细考虑这些问题,那么生成错误代码是非常容易的。这就是说...
你应该可以使用正则表达式。嵌套可能会使它稍微复杂一些,但仍然可行(取决于您期望在嵌套场景中匹配的内容)。类似的东西应该让你开始:
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);
将上面的代码包装成适合您需要的函数应该是微不足道的。
您可以使用正则表达式,但记得要打电话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选项,这样它将匹配即使有新行文字。
下面是一个不使用正则表达式并且不考虑嵌套的解决方案。
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);
}
}
我很无聊,所以我做了一个无用的微基准,这“证明”(在我的数据集,其中有串起来的字符7K和<b>
标签的开始/结束参数)我怀疑juharr的解决方案是整体三者中速度最快的。
结果(1000000次迭代* 20测试用例):
juharr: 6371ms Jake: 6825ms Mark Byers: 82063ms
注:编译正则表达式并没有加快速度多在我的数据集。
自由正则表达式-方法:嵌套装置
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;
}
1级'[开始] XXX [开始] YYY [结束] ZZZ [结束]'是可能的? – kennytm 2010-03-30 20:17:02
这是不可能的。 – 2010-03-30 20:19:42
如果你这样做是为了解析HTML或XML,有更好的方法... – Randolpho 2010-03-30 20:22:19