我需要解析一个大字符串,我需要查找extract"(me,i-have lots. of]punctuation
的所有实例,并将每个的索引存储到列表中。
所以说这段字符串位于较大字符串的开头和中间,它们都会被找到,它们的索引会被添加到List
。并且List
将包含0
和另一个索引。
我一直在玩,string.IndexOf
几乎我正在寻找的东西,而且我已经写了一些代码 - 但它不起作用我已经无法确切地知道出了什么问题:
List<int> inst = new List<int>();
int index = 0;
while (index < source.LastIndexOf("extract\"(me,i-have lots. of]punctuation", 0) + 39)
{
int src = source.IndexOf("extract\"(me,i-have lots. of]punctuation", index);
inst.Add(src);
index = src + 40;
}
inst
=清单source
=大字符串有更好的想法吗?
答案 0 :(得分:112)
以下是一个示例扩展方法:
public static List<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
List<int> indexes = new List<int>();
for (int index = 0;; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
return indexes;
indexes.Add(index);
}
}
如果你把它放到一个静态类中并用using
导入命名空间,它就会在任何字符串上显示为一个方法,你可以这样做:
List<int> indexes = "fooStringfooBar".AllIndexesOf("foo");
有关扩展方法的详细信息,请http://msdn.microsoft.com/en-us/library/bb383977.aspx
使用迭代器也一样:
public static IEnumerable<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
for (int index = 0;; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
break;
yield return index;
}
}
答案 1 :(得分:14)
为什么不使用内置的RegEx类:
public static IEnumerable<int> GetAllIndexes(this string source, string matchString)
{
matchString = Regex.Escape(matchString);
foreach (Match match in Regex.Matches(source, matchString))
{
yield return match.Index;
}
}
如果确实需要重用表达式,则编译它并将其缓存到某处。将matchString参数更改为另一个重载中的Regex matchExpression以用于重用案例。
答案 2 :(得分:8)
使用LINQ
public static IEnumerable<int> IndexOfAll(this string sourceString, string subString)
{
return Regex.Matches(sourceString, subString).Cast<Match>().Select(m => m.Index);
}
答案 3 :(得分:5)
抛光版+忽略支持的案例:
public static int[] AllIndexesOf(string str, string substr, bool ignoreCase = false)
{
if (string.IsNullOrWhiteSpace(str) ||
string.IsNullOrWhiteSpace(substr))
{
throw new ArgumentException("String or substring is not specified.");
}
var indexes = new List<int>();
int index = 0;
while ((index = str.IndexOf(substr, index, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) != -1)
{
indexes.Add(index++);
}
return indexes.ToArray();
}
答案 4 :(得分:2)
可以使用O(N + M)中的KMP算法在高效的时间复杂度下完成,其中N是text
的长度,M是pattern
的长度。 / p>
这是实现和用法:
static class StringExtensions
{
public static IEnumerable<int> AllIndicesOf(this string text, string pattern)
{
if (string.IsNullOrEmpty(pattern))
{
throw new ArgumentNullException(nameof(pattern));
}
return Kmp(text, pattern);
}
private static IEnumerable<int> Kmp(string text, string pattern)
{
int M = pattern.Length;
int N = text.Length;
int[] lps = LongestPrefixSuffix(pattern);
int i = 0, j = 0;
while (i < N)
{
if (pattern[j] == text[i])
{
j++;
i++;
}
if (j == M)
{
yield return i - j;
j = lps[j - 1];
}
else if (i < N && pattern[j] != text[i])
{
if (j != 0)
{
j = lps[j - 1];
}
else
{
i++;
}
}
}
}
private static int[] LongestPrefixSuffix(string pattern)
{
int[] lps = new int[pattern.Length];
int length = 0;
int i = 1;
while (i < pattern.Length)
{
if (pattern[i] == pattern[length])
{
length++;
lps[i] = length;
i++;
}
else
{
if (length != 0)
{
length = lps[length - 1];
}
else
{
lps[i] = length;
i++;
}
}
}
return lps;
}
这是如何使用它的示例:
static void Main(string[] args)
{
string text = "this is a test";
string pattern = "is";
foreach (var index in text.AllIndicesOf(pattern))
{
Console.WriteLine(index); // 2 5
}
}
答案 5 :(得分:1)
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;
}
这样称呼:
List<int> list = GetPositions("bob is a chowder head bob bob sldfjl", "bob");
// list will contain 0, 22, 26
答案 6 :(得分:1)
@Matti Virkkunen的好回答
public static List<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
List<int> indexes = new List<int>();
for (int index = 0;; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
return indexes;
indexes.Add(index);
index--;
}
}
但这包括像AOOAOOA这样的测试案例 where substring
是AOOA和AOOA
输出0和3
答案 7 :(得分:1)
没有Regex,使用字符串比较类型:
string search = "123aa456AA789bb9991AACAA";
string pattern = "AA";
Enumerable.Range(0, search.Length)
.Select(index => { return new { Index = index, Length = (index + pattern.Length) > search.Length ? search.Length - index : pattern.Length }; })
.Where(searchbit => searchbit.Length == pattern.Length && pattern.Equals(search.Substring(searchbit.Index, searchbit.Length),StringComparison.OrdinalIgnoreCase))
.Select(searchbit => searchbit.Index)
这将返回{3,8,19,22}。空模式将匹配所有位置。
对于多种模式:
string search = "123aa456AA789bb9991AACAA";
string[] patterns = new string[] { "aa", "99" };
patterns.SelectMany(pattern => Enumerable.Range(0, search.Length)
.Select(index => { return new { Index = index, Length = (index + pattern.Length) > search.Length ? search.Length - index : pattern.Length }; })
.Where(searchbit => searchbit.Length == pattern.Length && pattern.Equals(search.Substring(searchbit.Index, searchbit.Length), StringComparison.OrdinalIgnoreCase))
.Select(searchbit => searchbit.Index))
这将返回{3,8,19,22,15,16}
答案 8 :(得分:1)
我注意到至少有两个提议的解决方案不能处理重叠搜索命中。我没有检查标有绿色复选标记的那个。这是处理重叠搜索命中的一个:
public static List<int> GetPositions(this string source, string searchString)
{
List<int> ret = new List<int>();
int len = searchString.Length;
int start = -1;
while (true)
{
start = source.IndexOf(searchString, start +1);
if (start == -1)
{
break;
}
else
{
ret.Add(start);
}
}
return ret;
}
答案 9 :(得分:0)
基于我用于在较大字符串中查找字符串的多个实例的代码,您的代码将如下所示:
List<int> inst = new List<int>();
int index = 0;
while (index >=0)
{
index = source.IndexOf("extract\"(me,i-have lots. of]punctuation", index);
inst.Add(index);
index++;
}
答案 10 :(得分:0)
@csam在理论上是正确的,虽然他的代码不会编译并且可以重构顶部>
public static IEnumerable<int> IndexOfAll(this string sourceString, string matchString)
{
matchString = Regex.Escape(matchString);
return from Match match in Regex.Matches(sourceString, matchString) select match.Index;
}
答案 11 :(得分:0)
public static Dictionary<string, IEnumerable<int>> GetWordsPositions(this string input, string[] Susbtrings)
{
Dictionary<string, IEnumerable<int>> WordsPositions = new Dictionary<string, IEnumerable<int>>();
IEnumerable<int> IndexOfAll = null;
foreach (string st in Susbtrings)
{
IndexOfAll = Regex.Matches(input, st).Cast<Match>().Select(m => m.Index);
WordsPositions.Add(st, IndexOfAll);
}
return WordsPositions;
}
答案 12 :(得分:-1)
我找到了这个example并将其合并到一个函数中:
public static int solution1(int A, int B)
{
// Check if A and B are in [0...999,999,999]
if ( (A >= 0 && A <= 999999999) && (B >= 0 && B <= 999999999))
{
if (A == 0 && B == 0)
{
return 0;
}
// Make sure A < B
if (A < B)
{
// Convert A and B to strings
string a = A.ToString();
string b = B.ToString();
int index = 0;
// See if A is a substring of B
if (b.Contains(a))
{
// Find index where A is
if (b.IndexOf(a) != -1)
{
while ((index = b.IndexOf(a, index)) != -1)
{
Console.WriteLine(A + " found at position " + index);
index++;
}
Console.ReadLine();
return b.IndexOf(a);
}
else
return -1;
}
else
{
Console.WriteLine(A + " is not in " + B + ".");
Console.ReadLine();
return -1;
}
}
else
{
Console.WriteLine(A + " must be less than " + B + ".");
// Console.ReadLine();
return -1;
}
}
else
{
Console.WriteLine("A or B is out of range.");
//Console.ReadLine();
return -1;
}
}
static void Main(string[] args)
{
int A = 53, B = 1953786;
int C = 78, D = 195378678;
int E = 57, F = 153786;
solution1(A, B);
solution1(C, D);
solution1(E, F);
Console.WriteLine();
}
返回:
在位置2找到53
在第4位找到78
78在第7位找到
57不在153786
答案 13 :(得分:-1)
这种替代实现方式如何?
public static class MyExtensions
{
public static int HowMany(this string str, char needle)
{
int counter = 0;
int nextIndex = 0;
for (; nextIndex != -1; )
{
nextIndex = str.IndexOf(needle, nextIndex);
if (nextIndex != -1)
{
counter++;
//step over to the next char
nextIndex++;
}
}
return counter;
}
}