【问题标题】:Extract specific number from string with fixed pattern in C#在 C# 中从具有固定模式的字符串中提取特定数字
【发布时间】:2016-02-18 10:47:26
【问题描述】:

这听起来像是一个非常基本的问题,但它给C# 带来了很多麻烦。

假设我有,例如,以下Strings 被称为我的chosenTarget.titles:

2008/SD128934 - Wordz aaaaand more words (1233-26-21)
20998/AD1234 - Wordz and less words (1263-21-21)
208/ASD12345 - Wordz and more words (1833-21-21)

现在您可以看到,所有三个Strings 在某些方面都不同。

我需要从这些Strings 中提取一个非常具体的部分,但正确处理这些细节让我感到困惑,我想知道你们中的一些人是否比我更了解。

我所知道的是Strings 将始终采用以下模式:

yearNumber + "/" + aFewLetters + theDesiredNumber + " - " + descriptiveText + " (" + someDate + ")"

在上面的例子中,我想要返回给我的是:

128934
1234
12345

我需要提取theDesiredNumber

现在,我并不(那么)懒惰,所以我自己做了一些尝试:

var a = chosenTarget.title.Substring(chosenTarget.title.IndexOf("/") + 1, chosenTarget.title.Length - chosenTarget.title.IndexOf("/"));

这样做是切掉yearNumber/,在theDesiredNumber 之前留下aFewLetter

但是,我很难正确移除其余部分,我想知道你们中的任何人是否可以在这件事上帮助我?

【问题讨论】:

  • 20820998 是几岁?真的是 208 和 20998?
  • 嘿,我刚刚制作了那些Strings 来适应这个例子。我想我复制的是2008,我只是添加和删除了多样性的数字,并证明我事先不知道一年的长度。
  • 对于这种情况,Regex 解决方案可能是最好的
  • 我更喜欢正则表达式。试试这个,例如:stackoverflow.com/questions/841883/… 和这个:stackoverflow.com/questions/21410065/…
  • 避免使用正则表达式。方式矫枉过正。从您当前拥有的内容中,只需找到char.IsDigit 返回true 的第一个索引,然后添加另一个Substring

标签: c# string


【解决方案1】:

听起来好像您只需要提取第一个/ 后面的数字,它以- 结尾。您可以结合使用字符串方法和 LINQ:

int startIndex = str.IndexOf("/");
string number = null;
if (startIndex >= 0 )
{
    int endIndex = str.IndexOf(" - ", startIndex);
    if (endIndex >= 0)
    {
        startIndex++;
        string token = str.Substring(startIndex, endIndex - startIndex); // SD128934
        number = String.Concat(token.Where(char.IsDigit)); // 128934
    }
}

另一种主要使用 LINQ 的方法,使用 String.Split

number = String.Concat(
            str.Split(new[] { " - " }, StringSplitOptions.None)[0]
              .Split('/')
              .Last()
              .Where(char.IsDigit));

【讨论】:

  • 很好的答案,但考虑到我对正则表达式知之甚少(我现在将对其进行更多研究!)并且蒂姆将答案保持在我有限的理解范围内,所以重点是他。跨度>
【解决方案2】:

试试这个:

 int indexSlash = chosenTarget.title.IndexOf("/");
 int indexDash = chosenTarget.title.IndexOf("-");
 string out = new string(chosenTarget.title.Substring(indexSlash,indexDash-indexSlash).Where(c => Char.IsDigit(c)).ToArray());

【讨论】:

    【解决方案3】:

    您可以使用正则表达式:

    var pattern = "(?:[0-9]+/\w+)[0-9]";
    var matcher = new Regex(pattern);
    var result = matcher.Matches(yourEntireSetOfLinesInAString);
    

    或者您可以循环每一行并使用 Match 而不是 Matches。在这种情况下,您不需要在每次迭代中都构建“匹配器”,而是在循环之外构建它

    【讨论】:

      【解决方案4】:

      正则表达式是你的朋友:

      (new [] {"2008/SD128934 - Wordz aaaaand more words (1233-26-21)",
      "20998/AD1234 - Wordz and less words (1263-21-21)",
      "208/ASD12345 - Wordz and more words (1833-21-21)"})
      .Select(x => new Regex(@"\d+/[A-Z]+(\d+)").Match(x).Groups[1].Value)
      

      【讨论】:

        【解决方案5】:

        你认识的模式很重要,解决方法如下:

        const string pattern = @"\d+\/[a-zA-Z]+(\d+).*$";
        string s1 = @"2008/SD128934 - Wordz aaaaand more words(1233-26-21)";
        string s2 = @"20998/AD1234 - Wordz and less words(1263-21-21)";
        string s3 = @"208/ASD12345 - Wordz and more words(1833-21-21)";
        var strings = new List<string> { s1, s2, s3 };
        var desiredNumber = string.Empty;
        
        foreach (var s in strings)
        {
            var match = Regex.Match(s, pattern);
            if (match.Success)
            {
                desiredNumber = match.Groups[1].Value;
            }
        }
        

        【讨论】:

          【解决方案6】:

          我会为此使用正则表达式,您要查找的字符串在 Match.Groups[1]

                  string composite = "2008/SD128934 - Wordz aaaaand more words (1233-26-21)";
                  Match m= Regex.Match(composite,@"^\d{4}\/[a-zA-Z]+(\d+)");
                  if (m.Success) Console.WriteLine(m.Groups[1]);
          

          RegEx的细分如下

          "^\d{4}\/[a-zA-Z]+(\d+)"
          
          ^           - Indicates that it's the beginning of the string
          \d{4}       - Four digits
          \/          - /
          [a-zA-Z]+   - More than one letters
          (\d+)       - More than one digits (the parenthesis indicate that this part is captured as a group - in this case group 1)
          

          【讨论】:

            猜你喜欢
            • 2013-01-30
            • 2019-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-18
            • 1970-01-01
            • 2020-02-02
            相关资源
            最近更新 更多