如何从字符串中获取字符串,以特定字符串开始和结束
How to get a string from a string, starting and ending with a specific string
我得到了一个包含如下类似文本的字符串
Name: John\n Surname: Smith\n Address: XXX\n
它可以以不同的顺序出现。
我想获取姓名值、姓氏值和地址值。
所以问题是:如何得到一个从字符串"Name: "开始到"\n"之前结束的字符串,所以我得到"John"而且代码可读性很好?
我尝试使用 Substring 函数,但它需要修改字符串,以便我获得“\n”部分的正确索引。而且我不希望修改原始字符串以使其更具可读性。
您可以将此字符串转换为字典(即一组键值对)。首先将初始字符串按换行符拆分为字符串数组。然后这个数组中的每个字符串用冒号分成两部分 - 键和值:
var input = "Name: John\n Surname: Smith\n Address: XXX\n";
var dictionary = input.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Split(':'))
.ToDictionary(p => p[0].Trim(), p => p[1].Trim());
然后通过键读取值:
var name = dictionary["Name"]; // gives you John
注意:如果允许地址或其他字段包含冒号,您可以在选择字典值时使用@Joel Coehoorn 评论中的string.Join选项。
或者您可以使用正则表达式而不是拆分和连接字符串。只需在您的输入中找到模式匹配:
var input = "Name: John\n Surname: Sm:ith\n Address: XX:X\n";
var dictionary = Regex.Matches(input, @"\s*([^:]+): ([^\n]+)\n").Cast<Match>()
.ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value);
var address = dictionary["Address"]; // XX:X
我会在这种情况下使用 Regex
,原因有两个:
- 在这些情况下更容易维护。
Substring
、Split
、Indexof
随着函数作用的增加,容易变得复杂。
- 它为未来的变化提供了更大的灵活性
下面是解析它的代码:
static string ExtractParam(string input, string arg) {
var match = Regex.Match(input, $@"\b{arg}:\s*(.*?)\n");
return match.Success ? match.Groups[1].Value : null;
}
static void Main() {
var input = "Name: John\n Surname: Smith\n Address: XXX\n";
var name = ExtractParam(input, "Name");
var surname = ExtractParam(input, "Surname");
var address = ExtractParam(input, "Address");
Console.WriteLine($"Name: {name}\n Surname: {surname}\n Address: {address}\n");
}
正则表达式非常容易理解。
\b : Match a word boundary
\s* : Eat up any unwanted whitespace
.*? : Match any string in a non-greedy way
() : Parenthesis are used to capture what we want to return
我得到了一个包含如下类似文本的字符串
Name: John\n Surname: Smith\n Address: XXX\n
它可以以不同的顺序出现。
我想获取姓名值、姓氏值和地址值。
所以问题是:如何得到一个从字符串"Name: "开始到"\n"之前结束的字符串,所以我得到"John"而且代码可读性很好?
我尝试使用 Substring 函数,但它需要修改字符串,以便我获得“\n”部分的正确索引。而且我不希望修改原始字符串以使其更具可读性。
您可以将此字符串转换为字典(即一组键值对)。首先将初始字符串按换行符拆分为字符串数组。然后这个数组中的每个字符串用冒号分成两部分 - 键和值:
var input = "Name: John\n Surname: Smith\n Address: XXX\n";
var dictionary = input.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Split(':'))
.ToDictionary(p => p[0].Trim(), p => p[1].Trim());
然后通过键读取值:
var name = dictionary["Name"]; // gives you John
注意:如果允许地址或其他字段包含冒号,您可以在选择字典值时使用@Joel Coehoorn 评论中的string.Join选项。
或者您可以使用正则表达式而不是拆分和连接字符串。只需在您的输入中找到模式匹配:
var input = "Name: John\n Surname: Sm:ith\n Address: XX:X\n";
var dictionary = Regex.Matches(input, @"\s*([^:]+): ([^\n]+)\n").Cast<Match>()
.ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value);
var address = dictionary["Address"]; // XX:X
我会在这种情况下使用 Regex
,原因有两个:
- 在这些情况下更容易维护。
Substring
、Split
、Indexof
随着函数作用的增加,容易变得复杂。 - 它为未来的变化提供了更大的灵活性
下面是解析它的代码:
static string ExtractParam(string input, string arg) {
var match = Regex.Match(input, $@"\b{arg}:\s*(.*?)\n");
return match.Success ? match.Groups[1].Value : null;
}
static void Main() {
var input = "Name: John\n Surname: Smith\n Address: XXX\n";
var name = ExtractParam(input, "Name");
var surname = ExtractParam(input, "Surname");
var address = ExtractParam(input, "Address");
Console.WriteLine($"Name: {name}\n Surname: {surname}\n Address: {address}\n");
}
正则表达式非常容易理解。
\b : Match a word boundary
\s* : Eat up any unwanted whitespace
.*? : Match any string in a non-greedy way
() : Parenthesis are used to capture what we want to return