我经常发现自己在进行字符串操作时编写了非常难看的代码。代码完成了预期的工作,但我希望对它的外观和执行情况感到满意。是否有任何好的书籍,网站,论坛解决常见的字符串操作问题?您将如何编写以下示例场景?
一个简单的场景:我有一组对象,我希望将每个对象上的特定方法的结果连接起来,并用“AND”分隔每个字符串。
这段代码可以解决这个问题,但是在编写一些漂亮的代码之后,它不会给你温暖舒适的感觉..;)。
List<MyClass> myColl = ..... // initialize the collection..
StringBuilder sb = new StringBuilder();
bool isFirst = true;
foreach (MyClass obj in myColl) {
if (!isFirst) {
sb.Append(" AND ");
}
isFirst = false;
sb.Append(obj.MyStringBuildingMethod());
}
如果我使用lambda表达式,这可能是一个更好的方法:
List<MyClass> myColl = ..... // initialize the collection..
string result = String.Join(" AND ", myColl.Select(i => i.MyStringBuildingMethod()).ToArray());
现在是一个更复杂的场景:我想在分隔符上拆分一个字符串,然后将每个部分拆分成一个键/值。该值用单引号括起来,如果分隔符在值内,我们不应该拆分它。下面的代码做了它应该做的事情,但感觉就像我使用了胶带或其他东西..;)
string csvString = "name='Andersson, Per',country='Sweden',city='Stockholm'";
Dictionary<string, string> keyValues = new Dictionary<string, string>();
bool isInsideQuote = false;
int lastPosition = 0;
for (int i = 0; i < csvString.Length; i++) {
if (csvString[i] == ',' && !isInsideQuote) {
string[] keyValuePair = csvString.Substring(lastPosition, i - lastPosition).Split("=".ToCharArray(), 2);
if (keyValuePair.Length == 2) {
keyValues.Add(keyValuePair[0], keyValuePair[1].TrimStart("'".ToCharArray()).TrimEnd("'".ToCharArray()));
}
lastPosition = i + 1;
}
if (csvString[i] == '\'') {
isInsideQuote = !isInsideQuote;
}
}
string[] lastKeyValuePair = csvString.Substring(lastPosition).Split("=".ToCharArray(), 2);
if (lastKeyValuePair.Length == 2) {
keyValues.Add(lastKeyValuePair[0], lastKeyValuePair[1].TrimStart("'".ToCharArray()).TrimEnd("'".ToCharArray()));
}
答案 0 :(得分:4)
您可以使用String.Join(string delimiter, string[] words)
方法。在C#3.0语法中,这可能如下所示:
var words = new string[]
{
"this",
"that",
"the other"
};
var concatenatedResult = String.Join(" and ", words);
//should output "this and that and the other"
Console.WriteLine(concatenatedResult);
如果您有通用列表并希望连接其值,则可以执行以下操作:
var words = new List<object>()
{
5,
DateTime.Now,
"something else"
};
var concatenatedResult = String.Join(" and ", words.Select(i => i.ToString()).ToArray());
//should output "5 and [system time] and something else"
Console.WriteLine(concatenatedResult);
Console.ReadLine();
请注意,第二个示例是从另一个StackOverflow帖子中删除的:Convert List(of object) to List(of string)。
我已经查看了IL的Join方法,如果不比使用StringBuilder类快,它应该在速度上具有合理的可比性。我想确保String类的实例没有在代码中连接,与OP中显示的方法相比,这将非常慢。
答案 1 :(得分:2)
我会为每条记录添加一个And,然后在最后删除最后一个And off ...
List<MyClass> myColl = ..... // initialize the collection..
StringBuilder sb = new StringBuilder();
foreach (MyClass obj in myColl)
sb.Append(obj.MyStringBuildingMethod() + " AND ");
string s = sb.ToString(0, sb.Length - 5);
答案 2 :(得分:0)
我认为这比你的第二个例子略微复杂,尽管它依赖于非常严格格式化的字符串。字符串解析并不总是很好。
string csvString = "name='Andersson, Per',country='Sweden',city='Stockholm'";
csvString = csvString.Replace("',", "'|");
string[] parts = csvString.Split('|');
foreach (string s in parts) {
string[] moreParts = s.Split('=');
string key = moreParts[0];
string value = moreParts[1].Trim("'");
// do stuff?
}