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

时间:2013-06-05 10:27:03

标签: c# string string-matching

我有一个格式的字符串列表:

全屏幕1

full1inc1

full1inc2

full1inc3

全屏幕2

full2inc1

full2inc2

FULL3

full100inc100

基本上,full之后的整数值可以是任何数字,“inc”可能存在也可能不存在。

我必须从此列表中选择一个任意字符串,例如“full32”或“full32inc1”,并将子字符串“full”与随后的数字隔离并将其放入另一个字符串中。我怎么想这样做?使用正则表达式或字符串匹配??

4 个答案:

答案 0 :(得分:1)

在一行中:

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 r = new Regex("(?<f>full32(inc\d+)?)");
foreach(Match m in r.Matches(yourString))
  MessageBox.Show(m.Groups["f"].Value);

在所有这些示例中,如果要在字符串中看到“full32”,那么如果要搜索除full32之外的字符串,则应使用变量进行参数化

答案 1 :(得分:1)

更新根据我对此问题的评论“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
));

如果您只想要“完整”之后的第一个数字:

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

Demo

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))

Demo

full1
full1_1
full1_2
full1_3
full2
full2_1
full2_2
full3
full100_100

答案 2 :(得分:1)

根据您的描述,似乎可能无法保证字符串的一致性。以下代码将根据未知内容的传入列表构造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,你就可以使用你喜欢的任何方法将这些分隔的线分成碎片并按你的喜好使用它们。

答案 3 :(得分:1)

最快捷的方式是蛮力,但就个人而言,我找到的最简单的方法是匹配特定的模式,在这种情况下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());