簡體   English   中英

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

[英]Find a substring within a string in C#

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

  • 滿1
  • full1inc1
  • full1inc2
  • full1inc3
  • 滿2
  • full2inc1
  • full2inc2
  • 滿3
  • ...
  • ....
  • full100inc100

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

我必須從這個列表中選擇一個任意字符串,假設是“full32”或“full32inc1”,然后將子字符串“full”與后面的數字分開,並將其放入另一個字符串中。

我怎么能這樣做? 我應該使用正則表達式還是字符串匹配?

在一行中:

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 以外的字符串,則應該使用變量進行參數化

根據對我的問題“ full100inc100的預期結果是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

根據您的描述,似乎不能保證字符串是一致的。 以下代碼將根據傳入的未知內容列表構造一個包含分隔(已解析)行的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 ,您就可以使用任何您喜歡的方式將這些分隔行分成幾段並StringNumberStringNumber使用它們。

最快的方法是蠻力,但就我個人而言,我發現最簡單的方法是匹配特定模式,在這種情況下, 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());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM