C# 这个字符串操作I';我在尝试吗?
我有以下格式的字符串: “[someTitle1]第一名$$[someTitle2]第二名$$[someTitle3]第三名$[someTitle4]第四名$[someTitle5]第五名$$[someTitle6]第六名” 我想从中接收以下字符串:C# 这个字符串操作I';我在尝试吗?,c#,string,C#,String,我有以下格式的字符串: “[someTitle1]第一名$$[someTitle2]第二名$$[someTitle3]第三名$[someTitle4]第四名$[someTitle5]第五名$$[someTitle6]第六名” 我想从中接收以下字符串: “thirdName.fourthName.fifthName.sixthName”(输入字符串的长度可能不同,但我希望始终获得最后四个元素(保证至少有4个) 我可以在一行内(或在其附近)执行此操作吗?Regex以捕获所有以']'开头的单词。然后从
“thirdName.fourthName.fifthName.sixthName”
(输入字符串的长度可能不同,但我希望始终获得最后四个元素(保证至少有4个)
我可以在一行内(或在其附近)执行此操作吗?Regex以捕获所有以']'开头的单词。然后从每个匹配中提取“值”。颠倒顺序,取前四个,然后再颠倒。然后用“.”连接它
var last4 =
new Regex(@"(?<=\])\w+")
.Matches(str)
.Cast<Match>()
.Select(match => match.Value)
.Reverse()
.Take(4)
.Reverse()
.Aggregate((a,b) => a + '.' + b);
var last4=
新正则表达式(@“(?假设您始终至少有4对标题/名称对,您可以先在$$
上进行拆分,然后使用skip获取最后4对,然后在]
上进行拆分,以仅获取名称部分。请注意,您可能需要添加检查,以确保对
的长度至少为4,并且在执行plit on]
如果可能有与您的格式不匹配的输入,它实际上会产生两个结果。这还假设您的标题或名称中没有双问号或方括号
var pairs = str.Split(new[] { "$$" });
var lastFour = pairs.Skip(pairs.Length -4)
.Select(x => x.Split(']')[1]);
var result = string.Join(".", lastFour);
使用新的C#(仅限C#8.0、.NET Core),这将成为一个单行程序:
string result = String.Join('.', Regex.Split(input, @"(^|\$\$)\[\w+]")[^4..]);
请注意,此正则表达式使用$$[someTitle]
部分作为分隔符(或仅在开头使用[someTitle]
)
(^ |\$\$)
匹配行首(^
)或(\
)双精度$
用\
转义,因为$
在正则表达式中具有特殊含义“行尾”。[
也被转义,因为它表示字符集的开头。\w
表示字母数字字符。+
表示其中至少有一个字符,但可能有很多。如果标题中可能出现字母和数字以外的字符,则将\w+
替换为+?
(导致(^ | \$\$)\[.+?]
)其中
代表任何字符。+?
表示至少一个字符,但尽可能少,否则+
将消耗结尾]
直到最后一个]
使用.NET标准2.1/.NET Core 2.0,您可以使用新的TakeLast
LINQ扩展方法:
string result = String.Join(".", Regex.Split(input, @"(^|\$\$)\[\w+]").TakeLast(4));
对于其他版本的C#:
太多人开始使用Regex
来解决每个问题。然而,解析类似的东西正是Regex擅长的
首先创建一个模式:
private const string NameTitlePattern = @"\[(?<title>\w+)](?<name>\w+)[(\$\$)$]";
private static readonly Regex _nameTitleRegex = new Regex(NameTitlePattern);
及
按$$
拆分,然后按]
拆分?@GSerg按$$$
拆分是显而易见的,我的主要问题是去掉标题和它们的括号。你不必这样做。按]
拆分,你会在第二个元素中得到干净的名称,在第一个元素中得到垃圾。正则表达式应该真正搜索双问号作为匹配结束,因为名称可能包含非单词字符,甚至可能包含单个问号。您不需要调用ToArray
,因为字符串太多。Join
接受IEnumerable
是,但仅从.NET 5.0开始这是什么意思?string.Join接受了IEnumerable for…比如ever@pinkfloydx33,@juharr:看来你们都是对的。它是从.NET 4.0开始存在的,以字符串作为分隔符,从.NET Core 2.0/.NET Standard 2.1开始,以字符作为分隔符。我必须展开“应用于”部分才能看到它。
private const string NameTitlePattern = @"\[(?<title>\w+)](?<name>\w+)[(\$\$)$]";
private static readonly Regex _nameTitleRegex = new Regex(NameTitlePattern);
private const string NameTitleStuff =
@"[someTitle1]firstName$$[someTitle2]secondName$$[someTitle3]thirdName$$[someTitle4]fourthName$$[someTitle5]fifthName$$[someTitle6]sixthName";
var result = new List<KeyValuePair<string, string>>();
var matches = _nameTitleRegex.Matches(NameTitleStuff);
foreach (var match in matches.Cast<Match>())
{
var groups = match.Groups;
result.Add(new KeyValuePair<string, string>(groups["title"].ToString(), groups["name"].ToString()));
}
var result = matches
.Cast<Match>()
.Select(match => match.Groups)
.Select(groups => new KeyValuePair<string, string>(
groups["title"].ToString(),
groups["name"].ToString()))
.ToList();