分配变量并在 IF 评估中检查它

Assign variable and check it within an IF evaluation

我怀疑这能否完成,但我还是会问,因为这会使我的代码更具可读性。

我必须为各种子字符串控制一个大字符串,并根据找到的子字符串以不同的方式详细说明它。

目前我有一个嵌套的 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 {...}
}

我能想到的唯一其他方法是双重转换 IndexOf 函数:

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 {...}

有没有办法在 if() 语句中检查 IndexOf() 结果并将其分配给一个变量?

线上的东西
if ((position = mystring.IndexOf("my substring")) AndAlso position > 0) { ... }

或者关于更好地处理这样一段代码的任何提示?

使用Contains(),此外,如果您出于某种原因确实需要一个职位,请单独使用IndexOf()if (mystring.Contains("my substring")) { ... }

是的,你可以这样做,就像这样:

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
}

请注意,我使用 myString.IndexOf(...) >= 0 作为子字符串的索引可以是 0(即从第一个字符开始),并且 IndexOf 方法 returns -1 如果找到 none

但您可以像这样使用 string.Contains

var myString = "Hello World";

if (myString.Contains("World"))
{
    // Do whatever
}
else if (myString.Contains("Some Other Substring"))
{
    // Do whatever
}

如果您不明确需要子字符串的位置,这会更好,但如果需要,请使用第一个

从技术上讲,你可以把它写成

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 {...}

不过,我建议提取方法:

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

您可以将其用作

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

这听起来确实像是正后视正则表达式的工作: 正后视确保 (?<=) 中的字符串先于另一个字符串

存在

与带有 out 参数的 TryGet..approach 一起,它可以几乎成为一个衬里。

然而, 是未来的证明,因为它接受多个输入字符串进行搜索。构建正则表达式可能无法维护

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