Reputation: 67
I doubt this can be done but I'll ask anyway since it would make my code much more readable.
I have to control a large string for various substrings and elaborate it in different ways depending on the substring found.
At the moment I have a nested if like
position = mystring.IndexOf("my substring")
if (position>0)
{
position = mystring.IndexOf("somestring", position);
[...]
}
else
{
position = mystring.IndexOf("my substring2")
if (position>0)
{
position = mystring.IndexOf("somestring2", position);
[...]
}
else {...}
}
The only other way I can think of doing this is double casting the IndexOf function:
if (mystring.IndexOf("my substring")>0)
{
position = mystring.IndexOf("somestring", mystring.IndexOf("my substring"));
[...]
}
else if (mystring.IndexOf(mysubstring2)>0)
{
position = mystring.IndexOf("somestring2", mystring.IndexOf("my substring2"));
[...]
}
else {...}
Is there a way to check the IndexOf()
result and assign it to a variable all within the if()
statement?
Something on the line of
if ((position = mystring.IndexOf("my substring")) AndAlso position > 0) { ... }
or any tip on having such a piece of code handled better?
Upvotes: 2
Views: 7094
Reputation: 186668
Technically, you can put it as
int position;
if ((position = mystring.IndexOf("my substring")) > 0)
{
// Note, that you should use position + "my substring".Length if
// "somestring" can't be part of previous match
position = mystring.IndexOf("somestring", position);
[...]
}
else if ((position = mystring.IndexOf(mysubstring2)) > 0)
{
position = mystring.IndexOf("somestring2", position);
[...]
}
else {...}
However, I suggest extracting a method:
private static bool FindMany(string source, out int lastIndex, params string[] toFind) {
if (null == toFind)
throw new ArgumentNullException(nameof(toFind));
lastIndex = -1;
int result = -1;
if (string.IsNullOrEmpty(source))
return false;
int index = 0;
for (int i = 0; i < toFind.Length; ++i) {
result = source.IndexOf(toFind[i], index);
index += toFind[i].Length;
if (index < 0)
return false;
}
lastIndex = result;
return true;
}
Which you can use as
int position;
if (FindMany(mystring, out position, "my substring", "somestring") {
// "my substring" found
if (position >= 0) {
// "somestring" is found as well; its index - position
...
}
else {
// only "my substring" has been found
}
}
else if (FindMany(mystring, out position, "my substring2", "somestring2") {
// "my substring2" found
if (position >= 0) {
// "somestring2" is found
...
}
}
Upvotes: 1
Reputation: 11635
this does sound like a job for regex with positive lookbehind:
a positive lookbehind makes sure that the string inside (?<=)
exists prior to the other string
Together with a TryGet..approach with an out parameter it can almost become a one liner.
However, Dmitrys solution is a tad more future proof, since it accepts multiple input strings to search for. Building that regex could prove unmaintainable
https://dotnetfiddle.net/D5WFyx
using System;
using System.Text.RegularExpressions;
public static void Main()
{
string input = "here is my substring and then somestring";
int position;
if (TryGetIndex(input, "(?<=my substring.*)somestring", out position)){
Console.WriteLine($"somestring index: {position}");
}
else if (TryGetIndex(input, "(?<=other substring.*)otherstring", out position)) {
Console.WriteLine($"otherstring index: {position}");
}
bool TryGetIndex(string input, string pattern, out int position){
var match = Regex.Match(input, pattern);
if (match.Success){
position = match.Index;
return true;
}
position = -1;
return false;
}
}
Upvotes: 0
Reputation: 7855
Yes you can do it, like so:
var myString = "Hello World";
int pos;
if ((pos = myString.IndexOf("World")) >= 0)
{
Console.WriteLine(pos); // prints 6
}
else if ((pos = myString.IndexOf("Some Other Substring")) >= 0)
{
// Do whatever
}
Note that I'm using myString.IndexOf(...) >= 0
as the index of the substring could be 0 (i.e starting at the first character), and the IndexOf
method returns -1
if none was found
But you could rather just use string.Contains
like so:
var myString = "Hello World";
if (myString.Contains("World"))
{
// Do whatever
}
else if (myString.Contains("Some Other Substring"))
{
// Do whatever
}
This is better if you don't explicitly need the location of the substring, but if you do, use the first one
Upvotes: 4
Reputation: 458
Use Contains()
and, in addition, use IndexOf()
separately if you really need to have a position by some reason. if (mystring.Contains("my substring")) { ... }
Upvotes: 0