在字符后用空格/两个空格分割字符串

Posted

技术标签:

【中文标题】在字符后用空格/两个空格分割字符串【英文标题】:Splitting a string with a space/two spaces after the character 【发布时间】:2020-05-16 15:24:37 【问题描述】:

考虑一些字符串,假设它们包含“Wxxx”形式的“键”,其中 x 是从 0 到 9 的数字。每一个可以只包含一个,也可以包含多个,用“,”分隔,后跟两个空格。例如:

W123
W432
W546,  W234,  W167

包含多个“键”的那些需要拆分成一个数组。所以,上面例子中的最后一个应该被拆分成这样的数组:"W546", "W234", "W167"

作为一种快速解决方案,我想到了String.Split,但据我所知,它可以包含一个字符,例如“,”。问题是它会返回一个像这样的数组:"W546", " W234", " W167"。从第二个开始的所有数组条目中的两个空格可能可以使用Substring 删除,但是有更好的解决方案吗?

就上下文而言,这些值保存在电子表格中,并假定已经过数据验证,以确保“键”以逗号分隔,后跟两个空格。

while ((ws.Cells[row,1].Value!=null) && (ws.Cells[row,1].Value.ToString().Equals("")))

    // there can be one key, or multiple keys separated by ','
    if (ws.Cells[row,keysCol].Value.ToString().Contains(','))
    
        // there are multiple
        // need to split the ones in this cell separated by a comma           
    
    else
    
        // there is one
    

    row++;

【问题讨论】:

Split 可以将字符串数组作为参数。那不能解决你的问题。如果您的数据不是完全固定的格式,您也可以拆分多个逗号/空格变体 始终检查问题的格式。前两个值位于不同行的事实在格式中丢失了。 【参考方案1】:

您可以指定','' ' 作为分隔符和RemoveEmptyEntries

使用您的单个键示例和包含多个键的字符串,您可以完全一样地处理它们并获取单个键的列表:

List<string> cells = new List<string>()  "W123", "W432", "W546,  W234,  W167" ;
List<string> keys = new List<string>();

foreach (string cell in cells)

    keys.AddRange(cell.Split(new char[]  ',', ' ' , StringSplitOptions.RemoveEmptyEntries));

Split 可以处理无需拆分的字符串,AddRange 将接受您的单键以及多键拆分结果。

【讨论】:

仅供参考,前两个值实际上在不同的行上。问题的格式导致它们都显示为一行。 现在看起来它不是单独的行,而只是数据的 3 个示例,因此仅需要对用逗号和两个空格分隔的 3 个值进行拆分。【参考方案2】:

你可以使用一个旧的最爱——正则表达式。

这里有两种风格“循环”或“LINQ”。

    static void Main(string[] args)
    
        var list = new List<string>"W848","W998, W748","W953, W9484, W7373","W888";

        Console.WriteLine("LINQ");
        list.ForEach(l => TestSplitRegexLinq(l));

        Console.WriteLine();
        Console.WriteLine("Loop");
        list.ForEach(l => TestSplitRegexLoop(l));
    


    private static void TestSplitRegexLinq(string s)
    
        string pattern = @"[W][0-9]*";                
        var reg = new Regex(pattern);
        reg.Matches(s).ToList().ForEach(m => Console.WriteLine(m.Value));
    



    private static void TestSplitRegexLoop(string s)
    
        string pattern = @"[W][0-9]*";                
        var reg = new Regex(pattern);
        foreach (Match m in reg.Matches(s))
        
            Console.WriteLine(m.Value);
        
    

只需将Console.Write 替换为您想要的任何内容:例如。 myList.Add(m.Value).

您需要添加命名空间:using System.Text.RegularExpressions;

【讨论】:

... now you have two problems ... 只是说说而已。 @Filburt:感谢您提供的链接。我真的很喜欢阅读。不确定您的意图,但我的结论是:“我喜欢正则表达式。” - 爱可能太强烈了,但没关系。 “正则表达式摇滚。它们绝对应该是每个现代编码器工具包的关键部分。” - 也许不是“关键部分”,但每个开发人员都应该意识到优势和劣势。 “..regex 非常强大和简洁。” - 有时候是。在我上面的回答中,绝对。 “如果你害怕正则表达式,不要害怕。从小处着手。” - 它不会比以下更简单或更小:[W][0-9]* :: sage ich nur 肯定是编码恐怖的瑰宝之一。只是觉得你的回答需要我的 +1 来配合。【参考方案3】:

先消除多余的空间(使用Replace()),然后使用split。

var input = "W546, W234, W167";
var normalized = input.Replace(", ",",");  
var array = normalized.Split(',');

这样,您对待逗号后跟一个空格的方式与对待逗号的方式完全相同。如果可能有两个空格,您也可以替换它:

var input = "W546,  W234, W167";
var normalized = input.Replace("  "," ").Replace(", ",",");  
var array = normalized.Split(',');

【讨论】:

所以问题的格式不正确。前两个值实际上位于不同的行上。 我明白了。我调整了答案。 它们实际上位于不同的 Excel 单元格中。 Epplus 库用于逐个检查单元格的值,如果有多个,则尝试拆分它们。我将在原始帖子中添加一些代码来说明这一点。【参考方案4】:

在.NET fiddle中尝试过这个之后,我想我可能有一个解决方案:

// if there are multiple
string keys = ws.Cells[row,keysCol].Value.ToString();

// remove spaces
string keys_normalised = keys.Replace(" ", string.Empty);
Console.WriteLine("Checking that spaces have been removed: " + keys3_normalised + "\n");

string[] splits = keys3_normalised.Split(',');
for (int i = 0; i < splits.Length; i++)

    Console.WriteLine(splits[i]);

这会在控制台中产生以下输出:

Checking that spaces have been removed: W456,W234,W167

W456
W234
W167

【讨论】:

以上是关于在字符后用空格/两个空格分割字符串的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 分割字符串

Java开发自学技巧!java分割字符串split空格

如何分割“以空格分割的字符串中间还有空格”的数据结构

在空格处分割R字符串,但当空格在单引号之间时不分割

用空格和冒号分割字符串,但如果在引号内则不分割

JAVA 一个或多个空格分割字符串