C# 基于最后N个分隔符拆分字符串

C# 基于最后N个分隔符拆分字符串,c#,C#,我需要帮助开发分割字符串的逻辑,但仅基于字符串的最后2个分隔符 输入示例: string s1 = "Dog \ Cat \ Bird \ Cow"; string s2 = "Hello \ World \ How \ Are \ You"; string s3 = "I \ am \ Peter"; 预期产出: string[] newS1 = "Dog Cat", "Bird", "Cow" string[] newS2 = "Hello World How", "Are", "Yo

我需要帮助开发分割字符串的逻辑,但仅基于字符串的最后2个分隔符

输入示例:

string s1 = "Dog \ Cat \ Bird \ Cow";

string s2 = "Hello \ World \ How \ Are \ You";

string s3 = "I \ am \ Peter";
预期产出:

string[] newS1 = "Dog Cat", "Bird", "Cow"
string[] newS2 = "Hello World How", "Are", "You"
string[] newS3 = "I", "am", "Peter"
因此,正如您所看到的,我只想拆分最后2“\”上的字符串,而最后2“\”之前的所有内容都将连接到一个字符串中

我尝试了.Split方法,但它只会分割字符串中的每个“\”

编辑:如果字符串少于2“\”,它将根据它所具有的内容进行拆分

更新:哇,这是一堆有趣的解决方案!多谢各位


简单地获取拆分的输出,然后获取前N-2个项并将其连接在一起,然后创建包含3个项的新字符串数组,第一个是Join的输出,第二个是第一个拆分的N-1项,第三个是第一个拆分的N项。我想这会完成你想做的事。

有趣的问题。我的初步解决方案是:

String[] tokens = theString.Split("\\");
String[] components = new String[3];
for(int i = 0; i < tokens.length - 2; i++)
{
    components[0] += tokens[i];
}

components[1] = tokens[tokens.length - 2];
components[2] = tokens[tokens.length - 1];
String[]tokens=theString.Split(\\”;
字符串[]组件=新字符串[3];
for(int i=0;i
试试这个:

var parts = s1.Split(new[] { " \\ " }, StringSplitOptions.None);
var partsCount = parts.Count();
var result = new[] { string.Join(" ", parts.Take(partsCount - 2)) }.Concat(parts.Skip(partsCount - 2));

从字符串结尾循环并计数分隔符,直到遇到两个分隔符。 在之前设置为-1的2个变量中记录索引位置

在循环之后,如果第一个变量是-1,则什么也不发生,返回整个字符串

若第二个变量为-1,则创建包含2个字符串的数组,使用子字符串拆分并返回

创建3个字符串的数组,使用来自两个变量的信息拆分,返回

希望您理解我的伪代码,如果您需要帮助,请给我一个注释。

看起来您想在每个
\
上添加字符串:

然后是中间有空格的东西,除了最后两部分:

// NOTE: Check that there are at least 2 parts.
string part0 = String.Join(" ", parts.Take(parts.Length - 2));
string part1 = parts[parts.Length - 2];
string part2 = parts[parts.Length - 1];
这将为您提供三个字符串,您可以将它们放入一个数组中

string[] newParts = new []{ part0, part1, part2 };
在本例中:

new [] { "Dog Cat", "Bird", "Cow" }
提供解决方案:

var output = Regex.Split(input, @"\s*\\\s*([^\\]*?)\s*\\\s*(?=[^\\]*$)");
此拆分查找倒数第二个元素并围绕该元素拆分,但将其捕获到一个组中,以便将其包含在输出数组中

对于输入
“Dog\Cat\Bird\Cow”
,这将产生
{“Dog\Cat”、“Bird”、“Cow”}
。如果您还需要从第一个元素中剥离
\
,只需简单更换即可:

output[0] = output[0].Replace(" \\", "");

更新:此版本将正确处理只有一个分隔符的字符串:

var output = Regex.Split(str, @"\s*\\\s*([^\\]*?)\s*\\\s*(?=[^\\]*$)|(?<=^[^\\\s]*)\s*\\\s*(?=[^\\\s]*$)");
此正则表达式的结构比前一个稍简单,因为它表示类
[%~\s\\\]
中一个或多个字符的任意序列作为分隔符,而求反字符类
[^%~\s\\\]
中一个或多个字符的任意序列作为段。请注意,
\s
表示

您还可以使用以下方法进一步简化此过程:

var output = Regex.Split(str, @"(?:\W+(\w+)\W+|(?<=^\w+)\W+)(?=\w+$)");

var output=Regex.Split(str,@“(?:\W+(\W+)\W+|(?为什么要向下投票?这种方法可能是这里速度最快、内存效率最高的方法。它更适合作为注释,但这确实是一个答案。它包含了足够的信息,可以从中创建解决方案。注释用于询问更多信息。是的,这基本上就是我建议的,只是很好地编码了。唯一的注释是根据“规范”所有分隔符都被删除,因此我认为第一个要加入的参数应该是空格或空字符串。这将导致使用
{“Dog\Cat”,“Bird”,“Cow”}
的枚举,而不是使用
{“Dog Cat”,“Bird”,“Cow”}的数组
如所问。@Virtlink谢谢,已编辑!我可能会接受你的回答,因为它更清楚一点。是的,我喜欢采取一步一步的方法,向OP展示我是如何编写代码的。它还确保每个步骤都是正确的,并且可以编译,而你的代码目前没有(在我的LINQPad中)。您的
拆分中有一个错误,没有只使用字符串数组的重载。而且输出仍然不理想:
{“Dog\uuuuuuuuu Cat”、“Bird”、“Cow”}
是的,从内存编码,忘记了重载需要StringSplitOptions。公平地说,OP的问题也没有编译,因为它们没有逃过斜杠!你的代码甚至没有编译。但是如果编译了,它将返回
{“Dog\uu Cat”,“Bird”,“Cow”}
而不是
{“Dog Cat”,“Bird”,“Cow”}
如所问。谢谢你的提醒。顺便说一句,我喜欢你的答案。如果你的答案是编译的,我也希望你的答案。我喜欢使用,只需将你的代码粘贴在那里,看看它是否编译以及它产生了什么。我真的很喜欢这个创造性的解决方案!Regex总是让我惊讶+1@p.s.w.g你能教我怎样把你的表情改成英语吗匹配其他分隔符?(我需要一个空格“~”和“%”)。哇,这是一个解释得很好的答案。+1删除第一个元素中的“\”是有意的
var output = Regex.Split(str, @"(?:[%~\s\\]+([^%~\s\\]+?)[%~\s\\]+|(?<=^[^%~\s\\]+)[%~\s\\]+)(?=[^%~\s\\]+$)");
var output = Regex.Split(str, @"(?:\W+(\w+)\W+|(?<=^\w+)\W+)(?=\w+$)");