2017-06-06 145 views
1

我已經得到了含有類似的文字像下面如何從一個字符串得到一個字符串,開始和一個特定的字符串

Name: John\n Surname: Smith\n Address: XXX\n 

它可以在不同的順序出現的字符串結束。

我想獲得名稱值,姓氏值和地址值。

所以問題是:如何獲得從字符串「Name:」開始並在「\ n」之前結束的字符串,所以我得到「John」並且代碼非常易讀?

我試過使用Substring函數,但它需要對字符串進行操作,所以我得到了「\ n」部分的正確索引。而且我不想修改原始字符串,因此它更具可讀性。

+0

*我試圖使用Substring函數* - 你可以添加你試過的代碼嗎?並澄清什麼*它可以以不同的順序出現*意味着 –

+0

什麼版本的C#/ .Net? –

+0

最簡單的方法是使用'String'類的'Split'方法,使用分隔符''\ n'' ..... – t0mm13b

回答

3

您可以將此字符串轉換爲字典(即鍵值對)。首先通過換行符將初始字符串拆分爲字符串數組。然後從該陣列由結腸分爲兩個部分的每個字符串 - 鍵和值:

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 
+0

對於該值,可能是'string.Join(「:」,p.Skip(1).ToArray())',以說明可能在值中包含冒號的地址或其他項目。 –

+0

@JoelCoehoorn同意,地址可以包含冒號'string.Join(「:」,p.Skip(1))'將完成這項工作。謝謝 –

+0

我不確定在哪裏使用「string.Join(」:「,p.Skip(1))」行 –

1

我會在這些類型的情況下使用Regex原因有二:

  1. 這是比較容易保持它在這些情況下。當函數的作用增加時,Substring,Split,Indexof容易變得複雜。
  2. 它提供了更多的靈活性,爲未來的改變

下面是分析它的代碼:

static string ExtractParam(string input, string arg) { 
    var match = Regex.Match(input, [email protected]"\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 
0

@Vikhram的答案是非常好的:)

,我去給你其他的想法。 我的程序的工作方式有些不同,它會發現所有的指數法在字符串中包含「N」,而這會從最後打印字符串「\ n」「\ n」

 string test = "Name: John\n Surname: Smith\n Address: XXX\n"; 

     int fst_index = test.IndexOf("\n"); 
     int snd_index = test.IndexOf("\n", fst_index+1); 
     int trd_index = test.IndexOf("\n", snd_index+1); 

     Console.WriteLine(test.Substring(fst_index, snd_index-fst_index)); 
     Console.WriteLine("SPACE ?"); 

     Console.WriteLine(test.Substring(snd_index, trd_index - snd_index)); 
     Console.WriteLine("SPACE ?"); 

如果你打算在長文本中使用它,你必須使用循環。

相關問題