在c#中查找字符串中的子字符串

本文关键字:字符串 查找 | 更新日期: 2023-09-27 18:16:55

我有一个字符串列表,格式如下:

  • full1
  • full1inc1
  • full1inc2
  • full1inc3
  • full2
  • full2inc1
  • full2inc2
  • full3
  • full100inc100

基本上,在"full"后面的整数值可以是任意数字和"inc"可能会,也可能不会。

我必须从这个列表中选择一个任意字符串,比方说full32"或者是full32inc1"并隔离子字符串 "full"与后面的数字一起放到另一个字符串中。

我怎么能这么做?我应该使用Regex还是字符串匹配?

在c#中查找字符串中的子字符串

一行:

var matches = yourString.Split("'r'n".ToCharArray()).Where(s => s.StartsWith("full32"));

需要LINQ,在概念上等同于:

string[] lines = yourString.Split("'r'n".ToCharArray());
List<string> matches = new List<string>();
foreach(string s in lines)
  if(s.StartsWith("full32"))
    matches.Add(s);

你可能更容易读懂。

如果你想使用Regex,像这样的东西可以捕获它们:

Regex r = new Regex("(?<f>full32(inc'd+)?)");
foreach(Match m in r.Matches(yourString))
  MessageBox.Show(m.Groups["f"].Value);

在所有这些例子中,当你在字符串中看到"full32"时,如果你想搜索除full32以外的字符串

,你就应该用一个变量来参数化它

根据您的描述,似乎可能无法保证字符串的一致性。下面的代码将基于传入的未知内容列表构造一个分隔(解析)行的List<String>。这是一种"蛮力"方法,但应该允许传入列表的灵活性。下面是代码:

List<String> list = new List<String>();
list.Add("full1");
list.Add("full1inc1");
list.Add("full1inc2");
list.Add("full1inc3");
list.Add("full2");
list.Add("full2inc1");
list.Add("full2inc2");
list.Add("full3");
List<String> lines = new List<String>();
foreach (String str in list)
{
    String tmp = String.Empty;
    StringBuilder sb1 = new StringBuilder();
    StringBuilder sb2 = new StringBuilder();
    foreach (Char ch in str.ToCharArray())
    {
        if (Char.IsLetter(ch))
        {
            if (!String.IsNullOrEmpty(sb2.ToString()))
            {
              tmp += sb2.ToString() + ",";
                sb2 = new StringBuilder();
            }
            sb1.Append(ch);
        }
        else
        {
            if (!String.IsNullOrEmpty(sb1.ToString()))
            {
                tmp += sb1.ToString() + ",";
                sb1 = new StringBuilder();
            }
            sb2.Append(ch);
        }
    }
    if (!String.IsNullOrEmpty(sb1.ToString()))
        tmp += sb1.ToString() + ",";
    if (!String.IsNullOrEmpty(sb2.ToString()))
        tmp += sb2.ToString() + ",";
    lines.Add(tmp);
    for (Int32 i = 0; i < lines.Count; i++)
        lines[i] = lines[i].TrimEnd(',');
}
因此,根据示例列表,您将得到以下结果:
full1  -->  "full,1"
full1inc1  -->  "full,1,inc,1"
full1inc2  -->  "full,1,inc,2"
full1inc3  -->  "full,1,inc,3"
full2  -->  "full,2"
full2inc1  -->  "full,2,inc,1"
full2inc2  -->  "full,2,inc,2"
full3  -->  "full,3"
full100inc100  -->  "full,100,inc,100"

使用此方法,您不需要假定"full"是前导字符串,或者后面跟着"inc"(或实际上任何东西)。

一旦您有了结果分隔的列表,并且因为您知道模式是StringNumberStringNumber,那么您就可以使用任何您喜欢的方法将这些分隔的行分割成块并按您喜欢的方式使用它们。

根据对我的问题" full100inc100的期望结果是什么"的评论更新

期望的结果是full100

那就这么简单:

var isolatedList = listOfString
.Select(str => "full" + new string(
    str.Reverse()               // this is a backwards loop in Linq
       .TakeWhile(Char.IsDigit) // this takes chars until there is a non-digit char
       .Reverse()               // backwards loop to pick the digit-chars in the correct order
       .ToArray()               // needed for the string constructor
));

如果你只想要"full"之后的第一个数字:

var isolatedList = listOfString
    .Where(str => str.StartsWith("full"))
    .Select(str => "full" + new string(str.Substring("full".Length)
                                          .TakeWhile(Char.IsDigit)
                                          .ToArray()));

full1
full1
full2
full3
full2
full1
full2
full3
full100

也许这:

var isolatedList = listOfString
    .Where(str => str.StartsWith("full"))
    .Select(str => "full" + string.Join("_", str.Substring("full".Length).Split(new[]{"inc"}, StringSplitOptions.None)))
    .ToList();

相应更改String.Join中的分隔符或直接使用没有linq的逻辑:

"full" + 
string.Join("_", 
    str.Substring("full".Length).Split(new[]{"inc"}, StringSplitOptions.None))

full1
full1_1
full1_2
full1_3
full2
full2_1
full2_2
full3
full100_100

最快的方法是使用蛮力,但我个人认为最简单的方法是匹配特定的模式,在这种情况下,full后面跟着一个数字。

string myString = "full1'nfull2s"; // Strings
List<string> listOfStrings = new List<string>(); // List of strings
listOfStrings.Add(myString);
Regex regex = new Regex(@"full[0-9]+"); // Pattern to look for
StringBuilder sb = new StringBuilder();
foreach(string str in listOfStrings) {
    foreach(Match match in regex.Matches(str)) { // Match patterns
        sb.AppendLine(match.Value);
    }
}
MessageBox.Show(sb.ToString());