0

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

  • 满1
  • 全1inc1
  • 全1inc2
  • 全1inc3
  • 满2
  • 全2inc1
  • 全2inc2
  • 满3
  • ...
  • ……
  • 全100inc100

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

我必须从这个列表中选择一个任意字符串,比如说“full32”或“full32inc1”,并将子字符串“full”与后面的数字隔离开,并将其放入另一个字符串中。

我怎么能这样做?我应该使用正则表达式还是字符串匹配?

4

4 回答 4

1

Based on your description, it seems like it might be possible that the strings are not guaranteed to be consistent. The following code will construct a List<String> of delimited (parsed) lines based on an incoming list of unknown content. It's a bit of a "brute force" method, but should allow for flexibility in the incoming list. Here is the code:

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(',');
}

So, based on your example list, here's what you will get:

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"

With this method, you will not need to presume that "full" is the leading string, or that it is followed by "inc" (or really anything at all).

Once you have the resulting delimited list, and because you know that the pattern is StringNumberStringNumber, you can then use whatever means you like to split those delimited lines into pieces and use them as you like.

于 2013-06-05T11:08:55.577 回答
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 以外的字符串,您应该使用变量进行参数化

于 2013-06-05T10:40:57.253 回答
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()));

演示

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
于 2013-06-05T10:42:24.753 回答
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());
于 2013-06-05T12:58:38.660 回答