Finding multiple indexes from source string - c#

Basically I need to do String.IndexOf() and I need to get array of indexes from the source string.
Is there easy way to get array of indexes?
Before asking this question I have Googled a lot, but have not found easy solution to solve this simple problem.

How about this extension method:
public static IEnumerable<int> IndexesOf(this string haystack, string needle)
{
int lastIndex = 0;
while (true)
{
int index = haystack.IndexOf(needle, lastIndex);
if (index == -1)
{
yield break;
}
yield return index;
lastIndex = index + needle.Length;
}
}
Note that when looking for "AA" in "XAAAY" this code will now only yield 1.
If you really need an array, call ToArray() on the result. (This is assuming .NET 3.5 and hence LINQ support.)

var indexs = "Prashant".MultipleIndex('a');
//Extension Method's Class
public static class Extensions
{
static int i = 0;
public static int[] MultipleIndex(this string StringValue, char chChar)
{
var indexs = from rgChar in StringValue
where rgChar == chChar && i != StringValue.IndexOf(rgChar, i + 1)
select new { Index = StringValue.IndexOf(rgChar, i + 1), Increament = (i = i + StringValue.IndexOf(rgChar)) };
i = 0;
return indexs.Select(p => p.Index).ToArray<int>();
}
}

You would have to loop, I suspect:
int start = 0;
string s = "abcdeafghaji";
int index;
while ((index = s.IndexOf('a', start)) >= 0)
{
Console.WriteLine(index);
start = index + 1;
}

Using a solution that utilizes regex can be more reliable, using the indexOf function can be unreliable. It will find all matches and indexes, not matching an exact phrase which can lead to unexpected results. This function resolves that by making use of the Regex library.
public static IEnumerable<int> IndexesOf(string haystack, string needle)
{
Regex r = new Regex("\\b(" + needle + ")\\b");
MatchCollection m = r.Matches(haystack);
return from Match o in m select o.Index;
}

Related

Find How many times an Anagram is contained in a String - asp.net c#

I need to find how many times the Anagrams are contained in a String like in this example:(the anagrams and the string itself)
Input 1(String) = thegodsanddogsweredogged
Input 2(String) = dog
Output(int) = 3
the output will be 3 because of these - (thegodsanddogsweredogged)
So far i managed to check how many times the word "dog" is contained in the string:
public ActionResult FindAnagram (string word1, string word2)
{
int ?count = Regex.Matches(word1, word2).Count;
return View(count);
}
This works to check how many times the word is contained but i still get an error: Cannot convert null to 'int' because it is a non-nulable value type.
So i need to check for how many times input 2 and the anagrams of input 2(dog,god,dgo,ogd etc) are contained in input 1?(int this case its 3 times-thegodsanddogsweredogged)
Thank you
I wanted to post a variation which is more readable at the cost of some runtime performance. Anton's answer is probably more performant, but IMHO less readable than it could be.
The nice thing about anagrams is that you know their exact length, and you can figure out all possible anagram locations quite easily. For a 3 letter anagram in a 100 letter haystack, you know that there are 98 possible locations:
0..2
1..3
2..4
...
96..98
97..99
These indexes can be generated quite easily:
var amountOfPossibleAnagramLocations = haystack.Length - needle.Length + 1;
var substringIndexes = Enumerable.Range(0, amountOfPossibleAnagramLocations);
At this point, you simply take every listed substring and test if it's an anagram.
var anagramLength = needle.Length;
int count = 0;
foreach(var index in substringIndexes)
{
var substring = haystack.Substring(index, anagramLength);
if(substring.IsAnagramOf(needle))
count++;
}
Note that a lot of this can be condensed into a single LINQ chain:
var amountOfPossibleAnagramLocations = haystack.Length - needle.Length + 1;
var anagramLength = needle.Length;
var anagramCount = Enumerable
.Range(0, amountOfPossibleAnagramLocations)
.Select(x => haystack.Substring(x, anagramLength))
.Count(substring => substring.IsAnagramOf(needle));
Whether it's more readable or not depends on how comfortable you are with LINQ. I personally prefer it (up to a reasonable size, of course).
To check for an anagram, simply sort the characters and check for equality. I used an extension method for the readability bonus:
public static bool IsAnagramOf(this string word1, string word2)
{
var word1Sorted = String.Concat(word1.OrderBy(c => c));
var word2Sorted = String.Concat(word2.OrderBy(c => c));
return word1Sorted == word2Sorted;
}
I've omitted things like case insensitivity or ignoring whitespace for the sake of brevity.
It would be better not to try to use Regex but write your own logic.
You can use a dictionary with key char - a letter of the word and value int - number of letter occurrences. And build such a dictionary for the word.
Anagrams will have similar dictionaries, so you can build a temp dictionary for each temp string built using the Windowing method over your str and compare it with the dictionary built for your word.
Here is my code:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var str = "thegodsanddogsweredogged";
var word = "dog";
Console.WriteLine("Word: " + word);
Console.WriteLine("Str: " + str);
Console.WriteLine();
var count = CountAnagrams(str, word);
Console.WriteLine("Count: " + count);
Console.ReadKey();
}
private static int CountAnagrams(string str, string word) {
var charDict = BuildCharDict(word);
int count = 0;
for (int i = 0; i < str.Length - word.Length + 1; i++) {
string tmp = "";
for (int j = i; j < str.Length; j++) {
tmp += str[j];
if (tmp.Length == word.Length)
break;
}
var tmpCharDict = BuildCharDict(tmp);
if (CharDictsEqual(charDict, tmpCharDict)) {
count++;
Console.WriteLine("Anagram: " + tmp);
Console.WriteLine("Index: " + i);
Console.WriteLine();
}
}
return count;
}
private static Dictionary<char, int> BuildCharDict(string word) {
var charDict = new Dictionary<char, int>();
foreach (var ch in word)
{
if (charDict.ContainsKey(ch))
{
charDict[ch] += 1;
}
else
{
charDict[ch] = 1;
}
}
return charDict;
}
private static bool CharDictsEqual(Dictionary<char, int> dict1, Dictionary<char, int> dict2)
{
if (dict1.Count != dict2.Count)
return false;
foreach (var kv in dict1) {
if (!dict2.TryGetValue(kv.Key, out var val) || val != kv.Value)
{
return false;
}
}
return true;
}
}
}
Possibly there is a better solution, but mine works.
P.S. About your error. You should change int? to int, because your View might expect non-nullable int type

What is a Unicode safe replica of String.IndexOf(string input) that can handle Surrogate Pairs?

I am trying to figure out an equivalent to C# string.IndexOf(string) that can handle surrogate pairs in Unicode characters.
I am able to get the index when only comparing single characters, like in the code below:
public static int UnicodeIndexOf(this string input, string find)
{
return input.ToTextElements().ToList().IndexOf(find);
}
public static IEnumerable<string> ToTextElements(this string input)
{
var e = StringInfo.GetTextElementEnumerator(input);
while (e.MoveNext())
{
yield return e.GetTextElement();
}
}
But if I try to actually use a string as the find variable then it won't work because each text element only contains a single character to compare against.
Are there any suggestions as to how to go about writing this?
Thanks for any and all help.
EDIT:
Below is an example of why this is necessary:
CODE
Console.WriteLine("HolyCow𪘁BUBBYY𪘁YY𪘁Y".IndexOf("BUBB"));
Console.WriteLine("HolyCow#BUBBYY#YY#Y".IndexOf("BUBB"));
OUTPUT
9
8
Notice where I replace the 𪘁 character with # the values change.
You basically want to find index of one string array in another string array. We can adapt code from this question for that:
public static class Extensions {
public static int UnicodeIndexOf(this string input, string find, StringComparison comparison = StringComparison.CurrentCulture) {
return IndexOf(
// split input by code points
input.ToTextElements().ToArray(),
// split searched value by code points
find.ToTextElements().ToArray(),
comparison);
}
// code from another answer
private static int IndexOf(string[] haystack, string[] needle, StringComparison comparision) {
var len = needle.Length;
var limit = haystack.Length - len;
for (var i = 0; i <= limit; i++) {
var k = 0;
for (; k < len; k++) {
if (!String.Equals(needle[k], haystack[i + k], comparision)) break;
}
if (k == len) return i;
}
return -1;
}
public static IEnumerable<string> ToTextElements(this string input) {
var e = StringInfo.GetTextElementEnumerator(input);
while (e.MoveNext()) {
yield return e.GetTextElement();
}
}
}

Occurrences of a List<string> in a string C#

Given
var stringList = new List<string>(new string[] {
"outage","restoration","efficiency"});
var queryText = "While walking through the park one day, I noticed an outage",
"in the lightbulb at the plant. I talked to an officer about",
"restoration protocol for public works, and he said to contact",
"the department of public works, but not to expect much because",
"they have low efficiency."
How do I get the overall number of occurances of all strings in stringList from queryText?
In the above example, I would want a method that returned 3;
private int stringMatches (string textToQuery, string[] stringsToFind)
{
//
}
RESULTS
SPOKE TOO SOON!
Ran a couple of performance tests, and this branch of code from Fabian was faster by a good margin:
private int stringMatches(string textToQuery, string[] stringsToFind)
{
int count = 0;
foreach (var stringToFind in stringsToFind)
{
int currentIndex = 0;
while ((currentIndex = textToQuery.IndexOf(stringToFind , currentIndex, StringComparison.Ordinal)) != -1)
{
currentIndex++;
count++;
}
}
return count;
}
Execution Time:
On a 10000 iteration loop using stopwatch:
Fabian: 37-42 milliseconds
lazyberezovsky StringCompare: 400-500 milliseconds
lazyberezovsky Regex: 630-680 milliseconds
Glenn: 750-800 milliseconds
(Added StringComparison.Ordinal to Fabians answer for additional speed.)
That might also be fast:
private int stringMatches(string textToQuery, string[] stringsToFind)
{
int count = 0;
foreach (var stringToFind in stringsToFind)
{
int currentIndex = 0;
while ((currentIndex = textToQuery.IndexOf(stringToFind , currentIndex, StringComparison.Ordinal)) != -1)
{
currentIndex++;
count++;
}
}
return count;
}
This LINQ query splits text by spaces and punctuation symbols, and searches matches ignoring case
private int stringMatches(string textToQuery, string[] stringsToFind)
{
StringComparer comparer = StringComparer.CurrentCultureIgnoreCase;
return textToQuery.Split(new []{' ', '.', ',', '!', '?'}) // add more if need
.Count(w => stringsToFind.Contains(w, comparer));
}
Or with regular expression:
private static int stringMatches(string textToQuery, string[] stringsToFind)
{
var pattern = String.Join("|", stringsToFind.Select(s => #"\b" + s + #"\b"));
return Regex.Matches(textToQuery, pattern, RegexOptions.IgnoreCase).Count;
}
If you want to count the words in the string that are in the other collection:
private int stringMatches(string textToQuery, string[] stringsToFind)
{
return textToQuery.Split().Intersect(stringsToFind).Count();
}
I like Tim's answer, but I try to avoid making too many strings to avoid performance issues, and I do like regular expressions, so here's another way to go:
private int StringMatches(string searchMe, string[] keys)
{
System.Text.RegularExpressions.Regex expression = new System.Text.RegularExpressions.Regex(string.Join("|", keys), System.Text.RegularExpressions.RegexOptions.IgnoreCase);
return expression.Matches(searchMe).Count;
}
This will match only the words of your TextToQuery:
The idea of this is to check if the index before and after the match is not a letter.
Also, I had to make sure to check if it's the start or end of the string.
private int stringMatchesWordsOnly(string textToQuery, string[] wordsToFind)
{
int count = 0;
foreach (var wordToFind in wordsToFind)
{
int currentIndex = 0;
while ((currentIndex = textToQuery.IndexOf(wordToFind, currentIndex, StringComparison.Ordinal)) != -1)
{
if (((currentIndex == 0) || //is it the first index?
(!Char.IsLetter(textToQuery, currentIndex - 1))) &&
((currentIndex == (currentIndex + wordToFind.Length)) || //has the end been reached?
(!Char.IsLetter(textToQuery, currentIndex + wordToFind.Length))))
{
count++;
}
currentIndex++;
}
}
return count;
}
Conclusion:
As you can see this approach is a bit messier than my other answer and will be less performant (Still more performant than the other answers, though). So it really depends on what you want to achieve.
If you have short words in your strings to find, you should probably take this answer, because e.g. an 'and' would obviously return too many matches with the first approach.
private int stringMatches(string textToQuery, string[] stringsToFind)
{
string[] splitArray = textToQuery.Split(new char[] { ' ', ',','.' });
var count = splitArray.Where(p => stringsToFind.Contains(p)).ToArray().Count();
return count;
}
This is a revision of Fabian Bigler's original answer. It is about a 33% speed improvement mostly because of StringComparison.Ordinal.
Here's a link for more info on this: http://msdn.microsoft.com/en-us/library/bb385972.aspx
private int stringMatches(string textToQuery, List<string> stringsToFind)
{
int count = 0, stringCount = stringsToFind.Count(), currentIndex;
string stringToFind;
for (int i = 0; i < stringCount; i++)
{
currentIndex = 0;
stringToFind = stringsToFind[i];
while ((currentIndex = textToQuery.IndexOf(stringToFind, currentIndex, StringComparison.Ordinal)) != -1)
{
currentIndex++;
count++;
}
}
return count;
}

Using linq to count substrings in a string?

I could use the following linq expression to count the number of occurrences of a word as follows:
string test = "And And And";
int j = test.Split(' ').Count(x => x.Contains("And"));
However what if I was searching for "And And", Is there a way to use linq to count words without using split. Do any of these methods take longer the O(n)?
You can use a regular expression:
string test = "And And And";
int j = Regex.Matches(test, "And").Cast<Match>().Count();
BTW, do you want to allow overlapping occurrences? i.e. if you're looking for "And And", do you consider that test contains 1 or 2 occurrences of it?
I found a clever solution that can be resolved serverside with most LINQ to ORMs:
string search = "foo";
int searchLength = search.Length;
var result = qry.Select(i => new { Object = i, Occurrences = (i.SomeProperty.Length - i.SomeProperty.Replace(search, "").Length) / searchLength });
The idea is to replace the substring by an empty string and then divide the difference in string length by the length of the search term.
You can use IndexOf:
string what = "And";
int count = 0;
int pos = -what.Length;
for (;;)
{
pos = input.IndexOf(what, pos + what.Length);
if (pos == -1) break;
count++;
}
This is not quite Linq, but you can also make an extension method like below. It is probably more efficient than any Linq solution:
public static int CountSubStrings(this string input, string delimiter, bool ignoreCase = false)
{
int instancesNo = 0;
int pos = 0;
while((pos = input.IndexOf(delimiter, pos, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture)) != -1)
{
pos += delimiter.Length;
instancesNo++;
}
return instancesNo;
}

Get the index of the nth occurrence of a string?

Unless I am missing an obvious built-in method, what is the quickest way to get the nth occurrence of a string within a string?
I realize that I could loop the IndexOf method by updating its start index on each iteration of the loop. But doing it this way seems wasteful to me.
You really could use the regular expression /((s).*?){n}/ to search for n-th occurrence of substring s.
In C# it might look like this:
public static class StringExtender
{
public static int NthIndexOf(this string target, string value, int n)
{
Match m = Regex.Match(target, "((" + Regex.Escape(value) + ").*?){" + n + "}");
if (m.Success)
return m.Groups[2].Captures[n - 1].Index;
else
return -1;
}
}
Note: I have added Regex.Escape to original solution to allow searching characters which have special meaning to regex engine.
That's basically what you need to do - or at least, it's the easiest solution. All you'd be "wasting" is the cost of n method invocations - you won't actually be checking any case twice, if you think about it. (IndexOf will return as soon as it finds the match, and you'll keep going from where it left off.)
That's basically what you need to do - or at least, it's the easiest solution. All you'd be "wasting" is the cost of n method invocations - you won't actually be checking any case twice, if you think about it. (IndexOf will return as soon as it finds the match, and you'll keep going from where it left off.)
Here is the recursive implementation (of the above idea) as an extension method, mimicing the format of the framework method(s):
public static int IndexOfNth(this string input,
string value, int startIndex, int nth)
{
if (nth < 1)
throw new NotSupportedException("Param 'nth' must be greater than 0!");
if (nth == 1)
return input.IndexOf(value, startIndex);
var idx = input.IndexOf(value, startIndex);
if (idx == -1)
return -1;
return input.IndexOfNth(value, idx + 1, --nth);
}
Also, here are some (MBUnit) unit tests that might help you (to prove it is correct):
using System;
using MbUnit.Framework;
namespace IndexOfNthTest
{
[TestFixture]
public class Tests
{
//has 4 instances of the
private const string Input = "TestTest";
private const string Token = "Test";
/* Test for 0th index */
[Test]
public void TestZero()
{
Assert.Throws<NotSupportedException>(
() => Input.IndexOfNth(Token, 0, 0));
}
/* Test the two standard cases (1st and 2nd) */
[Test]
public void TestFirst()
{
Assert.AreEqual(0, Input.IndexOfNth("Test", 0, 1));
}
[Test]
public void TestSecond()
{
Assert.AreEqual(4, Input.IndexOfNth("Test", 0, 2));
}
/* Test the 'out of bounds' case */
[Test]
public void TestThird()
{
Assert.AreEqual(-1, Input.IndexOfNth("Test", 0, 3));
}
/* Test the offset case (in and out of bounds) */
[Test]
public void TestFirstWithOneOffset()
{
Assert.AreEqual(4, Input.IndexOfNth("Test", 4, 1));
}
[Test]
public void TestFirstWithTwoOffsets()
{
Assert.AreEqual(-1, Input.IndexOfNth("Test", 8, 1));
}
}
}
private int IndexOfOccurence(string s, string match, int occurence)
{
int i = 1;
int index = 0;
while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
{
if (i == occurence)
return index;
i++;
}
return -1;
}
or in C# with extension methods
public static int IndexOfOccurence(this string s, string match, int occurence)
{
int i = 1;
int index = 0;
while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
{
if (i == occurence)
return index;
i++;
}
return -1;
}
After some benchmarking, this seems to be the simplest and most effcient solution
public static int IndexOfNthSB(string input,
char value, int startIndex, int nth)
{
if (nth < 1)
throw new NotSupportedException("Param 'nth' must be greater than 0!");
var nResult = 0;
for (int i = startIndex; i < input.Length; i++)
{
if (input[i] == value)
nResult++;
if (nResult == nth)
return i;
}
return -1;
}
Here I go again! Another benchmark answer from yours truly :-) Once again based on the fantastic BenchmarkDotNet package (if you're serious about benchmarking dotnet code, please, please use this package).
The motivation for this post is two fold: PeteT (who asked it originally) wondered that it seems wasteful to use String.IndexOf varying the startIndex parameter in a loop to find the nth occurrence of a character while, in fact, it's the fastest method, and because some answers uses regular expressions which are an order of magnitude slower (and do not add any benefits, in my opinion not even readability, in this specific case).
Here is the code I've ended up using in my string extensions library (it's not a new answer to this question, since others have already posted semantically identical code here, I'm not taking credit for it). This is the fastest method (even, possibly, including unsafe variations - more on that later):
public static int IndexOfNth(this string str, char ch, int nth, int startIndex = 0) {
if (str == null)
throw new ArgumentNullException("str");
var idx = str.IndexOf(ch, startIndex);
while (idx >= 0 && --nth > 0)
idx = str.IndexOf(ch, startIndex + idx + 1);
return idx;
}
I've benchmarked this code against two other methods and the results follow:
The benchmarked methods were:
[Benchmark]
public int FindNthRegex() {
Match m = Regex.Match(text, "((" + Regex.Escape("z") + ").*?){" + Nth + "}");
return (m.Success)
? m.Groups[2].Captures[Nth - 1].Index
: -1;
}
[Benchmark]
public int FindNthCharByChar() {
var occurrence = 0;
for (int i = 0; i < text.Length; i++) {
if (text[i] == 'z')
occurrence++;
if (Nth == occurrence)
return i;
}
return -1;
}
[Benchmark]
public int FindNthIndexOfStartIdx() {
var idx = text.IndexOf('z', 0);
var nth = Nth;
while (idx >= 0 && --nth > 0)
idx = text.IndexOf('z', idx + 1);
return idx;
}
The FindNthRegex method is the slower of the bunch, taking an order (or two) of magnitude more time than the fastest. FindNthByChar loops over each char on the string and counts each match until it finds the nth occurrence. FindNthIndexOfStartIdx uses the method suggested by the opener of this question which, indeed, is the same I've been using for ages to accomplish this and it is the fastest of them all.
Why is it so much faster than FindNthByChar? It's because Microsoft went to great lengths to make string manipulation as fast as possible in the dotnet framework. And they've accomplished that! They did an amazing job! I've done a deeper investigation on string manipulations in dotnet in an CodeProject article which tries to find the fastest method to remove all whitespace from a string:
Fastest method to remove all whitespace from Strings in .NET
There you'll find why string manipulations in dotnet are so fast, and why it's next to useless trying to squeeze more speed by writing our own versions of the framework's string manipulation code (the likes of string.IndexOf, string.Split, string.Replace, etc.)
The full benchmark code I've used follows (it's a dotnet6 console program):
UPDATE: Added two methods FindNthCharByCharInSpan and FindNthCharRecursive (and now FindNthByLinq).
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Text;
using System.Text.RegularExpressions;
var summary = BenchmarkRunner.Run<BenchmarkFindNthChar>();
public class BenchmarkFindNthChar
{
const string BaseText = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
[Params(100, 1000)]
public int BaseTextRepeatCount { get; set; }
[Params(500)]
public int Nth { get; set; }
private string text;
[GlobalSetup]
public void BuildTestData() {
var sb = new StringBuilder();
for (int i = 0; i < BaseTextRepeatCount; i++)
sb.AppendLine(BaseText);
text = sb.ToString();
}
[Benchmark]
public int FindNthRegex() {
Match m = Regex.Match(text, "((" + Regex.Escape("z") + ").*?){" + Nth + "}");
return (m.Success)
? m.Groups[2].Captures[Nth - 1].Index
: -1;
}
[Benchmark]
public int FindNthCharByChar() {
var occurrence = 0;
for (int i = 0; i < text.Length; i++) {
if (text[i] == 'z')
occurrence++;
if (Nth == occurrence)
return i;
}
return -1;
}
[Benchmark]
public int FindNthIndexOfStartIdx() {
var idx = text.IndexOf('z', 0);
var nth = Nth;
while (idx >= 0 && --nth > 0)
idx = text.IndexOf('z', idx + 1);
return idx;
}
[Benchmark]
public int FindNthCharByCharInSpan() {
var span = text.AsSpan();
var occurrence = 0;
for (int i = 0; i < span.Length; i++) {
if (span[i] == 'z')
occurrence++;
if (Nth == occurrence)
return i;
}
return -1;
}
[Benchmark]
public int FindNthCharRecursive() => IndexOfNth(text, "z", 0, Nth);
public static int IndexOfNth(string input, string value, int startIndex, int nth) {
if (nth == 1)
return input.IndexOf(value, startIndex);
var idx = input.IndexOf(value, startIndex);
if (idx == -1)
return -1;
return IndexOfNth(input, value, idx + 1, --nth);
}
[Benchmark]
public int FindNthByLinq() {
var items = text.Select((c, i) => (c, i)).Where(t => t.c == 'z');
return (items.Count() > Nth - 1)
? items.ElementAt(Nth - 1).i
: -1;
}
}
UPDATE 2: The new benchmark results (with Linq-based benchmark) follows:
The Linq-based solution is only better than the recursive method, but it's good to have it here for completeness.
Maybe it would also be nice to work with the String.Split() Method and check if the requested occurrence is in the array, if you don't need the index, but the value at the index
Or something like this with the do while loop
private static int OrdinalIndexOf(string str, string substr, int n)
{
int pos = -1;
do
{
pos = str.IndexOf(substr, pos + 1);
} while (n-- > 0 && pos != -1);
return pos;
}
System.ValueTuple ftw:
var index = line.Select((x, i) => (x, i)).Where(x => x.Item1 == '"').ElementAt(5).Item2;
writing a function from that is homework
Tod's answer can be simplified somewhat.
using System;
static class MainClass {
private static int IndexOfNth(this string target, string substring,
int seqNr, int startIdx = 0)
{
if (seqNr < 1)
{
throw new IndexOutOfRangeException("Parameter 'nth' must be greater than 0.");
}
var idx = target.IndexOf(substring, startIdx);
if (idx < 0 || seqNr == 1) { return idx; }
return target.IndexOfNth(substring, --seqNr, ++idx); // skip
}
static void Main () {
Console.WriteLine ("abcbcbcd".IndexOfNth("bc", 1));
Console.WriteLine ("abcbcbcd".IndexOfNth("bc", 2));
Console.WriteLine ("abcbcbcd".IndexOfNth("bc", 3));
Console.WriteLine ("abcbcbcd".IndexOfNth("bc", 4));
}
}
Output
1
3
5
-1
This might do it:
Console.WriteLine(str.IndexOf((#"\")+2)+1);

Categories