2010-02-22 77 views
6

字符串格式总是像这样“FirstName = ABC; LastName = XZY;用户名= User1;密码= 1234”。如何从一个字符串使用C#子字符串?

我需要唯一的UserName值(在这种情况下是'User1')。我想在使用子字符串方法(或其他)的最小代码行中实现这一点。

帮助?

+0

当一个问题有非常明确的答案像这样它总是一件有趣的我看有多少不同的解决方案多所社区提供。 –

+0

有一点需要注意:输入字符串有一个名为“User ** n ** name”的字段。然后您要求“User ** N ** ame”字段。解析字符串时要小心套话。当然有处理这个问题的方法。 –

回答

4

即使值对以不同的顺序给出,该方法仍然有效。它在分号上分开,用“用户名”找到该项目,然后返回等号后面的内容。

string theString = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
string username = theString.Split(";").Where(s => s.Split("=")[0].Equals("Username")).ToArray()[0].Split("=")[1]; 
+0

@Aaron:对不起,是语法oke。我正在接近.ToArray [0] ..错误。 – Jango

+0

@ user144842:您在我的示例中遇到了错误! ToArray之后应该有括号。我已经更新了我的答案。 – Aaron

+0

这将是一半VB和一半C#...可能都是他的头顶。 –

12

看起来像一个分隔的字符串,所以这会工作:

string result = myString.Split(';')[2].Split('=')[1]; 

但是,如果有人更改值对订单,这将打破。

有更好的方法可以解决这个问题,如果顺序改变,参数的数量不同等等 - 比如Michael发布的正则表达式,或者许多人发布的Linq查询。

+0

打我吧:( –

+3

我很欣赏你试图尽可能缩短它,但我认为我们有最近看到的最丑陋的代码的赢家(没有任何意图!) – brian

+0

我wouldn不要说它有史以来最丑陋的代码,但用户得到了他想要的东西..... –

4

最少的代码行数并不总是最好的指标,但你可以用正则表达式来做你所需要的。

+1

这有多奇怪,这可能是我见过正则表达式的第一次建议,它是一个有效的答案。 :p – Tanzelax

+0

难道你没有听说过 - 有些人在遇到问题时想:“我知道,我会用正则表达式。”现在他们有两个问题。杰米Zawinski – Oded

+0

@Tanzelax:正则表达式成为新的JQuery? – brian

1
 string t = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
     string name = t.Split(';')[2].Split('=')[1]; 
7

这里是一个替代的解决方案(从别人不太一样,但我认为这是更简单),无论其将工作秩序。

var input = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 

Assert.AreEqual("User1", input 
    .Split(';') 
    .Select(item => item.Split('=')) 
    .Where(pair => pair[0].Equals("Username")) 
    .Single()[1]); 
+0

当字符串没有“用户名”时失败。 –

+0

如果可能没有用户名,可以在'.Single()'之前添加'.Select(pair => pair [1])'并将'.Single()'改为'.SingleOrDefault()'。那么如果没有用户名,你就会得到空值。 –

15

为了完整起见,这里是正则表达式的方法。如果订单改变,这也将起作用。

// using System.Text.RegularExpressions; 

string test1 = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
string test2 = "FirstName=ABC;LastName=XZY;Password=1234;Username=User1"; 
string test3 = "FirstName=ABC;LastName=XZY;Password=1234"; 

string regexPattern = @"(?<=Username=)[^;\n]*"; 
var userName1 = Regex.Match(test1, regexPattern).Value; // User1 
var userName2 = Regex.Match(test2, regexPattern).Value; // User1 
var userName3 = Regex.Match(test3, regexPattern).Value; // string.Empty 

// Compiling can speed up the Regex, at the expense of longer initial Initialization 
// Use when this is called often, but measure. 

Regex compiledRx = new Regex(regexPattern,RegexOptions.Compiled); 
var userNameCompiled1 = compiledRx.Match(test1).Value; // User1 
var userNameCompiled2 = compiledRx.Match(test2).Value; // User1 
var userNameCompiled3 = compiledRx.Match(test3).Value; // string.Empty 
+1

这实际上是应用正则表达式的好地方。好东西。 –

3

虽然分裂的答案是“OK”,如果什么事也没发生变化,它可能会更好用的功能,因为:

  • 它使你的意图明显。
  • 更容易记录。
  • 如果发生不可避免的情况,修改会更容易。
  • 无论顺序如何工作。

(即使你只是把该函数的一个线分离或至少是注释添加到分割!)


static String GetUsername(String value) 
{ 
    String result = ""; 
    String token = "Username="; 

    int index = value.IndexOf(token) + token.Length; 
    while (value[index] != ';') 
    { 
     result += value[index++]; 
     if (index > value.Length - 1) 
      break; 
    } 

    return result; 
} 
+0

我喜欢封装这个“逻辑”的建议,但让我们变成邪恶的:他的样本并没有以';'结尾。现在想象一下“用户名=”部分到底是什么,你的解决方案会发生什么? –

+3

@Benjamin - 虽然不难处理这种情况;我认为所有提出的解决方案都存在一些缺陷。例如,如果字符串中有两个用户名呢?会发生什么?这个解决方案总是会选择第一个。无论如何,我认为这个微不足道的问题已经到了极点。 – 2010-02-22 19:30:18

+0

同意 - 以及+1 :) –

3

还不如不过采用分体式,就这么简单:

string input = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
string username = Regex.Match(input, "Username=(?<username>.*?)(;|$)").Groups["username"].Value; 

在这种情况下,组可以按任意顺序排列。

而且,如果你想获得创意:

var answers = from tuple in input.Split(';') 
       where tuple.StartsWith("Username=") 
       select tuple.Split('=')[1]; 

username = answers.Count() > 0 ? answers.First() : string.Empty; 

有人可能会说的最后一块具有更好的语义。

编辑:更新最后一块处理输入字符串没有所需的元组。

+0

如果源字符串是'FirstName = ABC;用户名= User1;姓名= XZY;密码= 1234',将会失败。使用'?'进行懒惰搜索:'用户名=(?。*?);' –

+0

@Naeem Sarfraz:谢谢,你是对的。该死的贪婪的东西。另外,我更正了用户名是字符串中最后一对的情况。现在REGEX是复杂的... –

1

这不是最短的......但可能是最快的之一。

string value = "FirstName=ABC;LastName=XZY;Username=User1;Password=1234"; 
int offset = value.IndexOf("Username=") + 9; 
if (offset < 9) 
    throw new Exception("Username= not found in string"); 
int len = value.IndexOf(';', offset) - offset; 
if (len < 0) 
    len = value.Length - offset; 
string find = value.Substring(offset, len); 

...的if (len < 0)是是用户名是在字符串的结束和不以分号结束。如果你想忽略情况下,你可以替换这个int offset线...

int offset = value.ToUpperInvariant().IndexOf("USERNAME=") + 9; 
+0

我知道“幻数”可以通过将“用户名=”移动到一个变量,如令牌和使用token.Length来代替。 –

+0

随时抱怨“例外”我不觉得有什么更好的例子。 –

相关问题