8

我正在编写一个小类来从文件中读取键值对列表并写入Dictionary<string, string>. 该文件将具有以下格式:

key1:value1
key2:value2
key3:value3
...

这应该很容易做到,但是由于用户要手动编辑这个文件,我应该如何处理空格、制表符、额外的行跳转和类似的东西?我可能可以使用 Replace 来删除空格和制表符,但是,我还缺少其他“不可见”字符吗?

或者,也许我可以删除所有非字母数字字符、“:”和换行符(因为换行符将一对与另一对分开),然后删除所有额外的换行符。如果是这样,我不知道如何删除“所有除外”字符。

当然,我也可以检查诸如“key1:value1:somethingelse”之类的错误。但是这样的事情并不重要,因为这显然是用户的错,我只会显示“格式无效”的消息。我只想处理基本的东西,然后把所有的东西放在一个 try/catch 块中,以防万一出现任何问题。

注意:我根本不需要任何空格,即使在键或值内也是如此。

4

7 回答 7

17

我最近做了这个,当时我终于对提要中出现太多无证垃圾形成坏 xml 感到恼火。它有效地修剪掉任何不在 ASCII 表中的空格和 ~ 之间的内容:

static public string StripControlChars(this string s)
{
    return Regex.Replace(s, @"[^\x20-\x7F]", "");
}

结合已经发布的其他 RegEx 示例,它应该可以让您到达您想去的地方。

于 2011-03-14T19:23:23.390 回答
7

如果你使用 Regex(正则表达式),你可以用一个函数过滤掉所有这些。

string newVariable Regex.Replace(variable, @"\s", "");

这将删除空格、不可见字符、\n 和 \r。

于 2011-03-14T19:16:34.903 回答
4

经常咬我们的“白色”空间之一是牢不可破的空间。此外,我们的系统必须与限制性更强的 MS-Dynamics 兼容。首先,我创建了一个函数,将第 8 位字符映射到它们近似的第 7 位对应字符,然后我删除了任何不在 x20 到 x7f 范围内的内容,进一步受到 Dynamics 接口的限制。

Regex.Replace(s, @"[^\x20-\x7F]", "")

应该做那份工作。

于 2011-03-14T19:30:48.983 回答
2
var split = textLine.Split(":").Select(s => s.Trim()).ToArray();

Trim() 函数将删除所有不相关的空格。请注意,这会在键或值内保留空格,您可能需要单独考虑。

于 2011-03-14T19:17:16.227 回答
2

您可以使用string.Trim()删除空格字符:

var results = lines
        .Select(line => {
            var pair = line.Split(new[] {':'}, 2);
            return new {
                Key = pair[0].Trim(),
                Value = pair[1].Trim(),
            };
        }).ToList();

但是,如果要删除所有空格,可以使用正则表达式:

var whiteSpaceRegex = new Regex(@"\s+", RegexOptions.Compiled);
var results = lines
        .Select(line => {
            var pair = line.Split(new[] {':'}, 2);
            return new {
                Key = whiteSpaceRegex.Replace(pair[0], string.Empty),
                Value = whiteSpaceRegex.Replace(pair[1], string.Empty),
            };
        }).ToList();
于 2011-03-14T19:18:05.347 回答
2

要求太模糊了。考虑:

“什么时候空格是值?键?”
“什么时候分隔符是值?键?”
“什么时候标签是一个值?键?”
“在值的上下文中使用分隔符时,值在哪里结束?键”?

这些问题将导致代码中充满了一次性和糟糕的用户体验。这就是我们有语言规则/语法的原因。

定义一个简单的语法并消除大部分猜测。

“{核心价值}”,

在这里,您有一个键/值对包含在引号中,并通过分隔符 (,) 分隔。所有无关的字符都可以忽略。您可以使用 XML,但这可能会吓跑技术含量较低的用户。

请注意,引号是任意的。随意替换任何不需要太多转义的集合容器(请注意复杂性)。

就个人而言,我会将其包装在一个简单的 UI 中,并将数据序列化为 XML。有时不这样做,但你没有给我不这样做的理由。

于 2011-03-14T19:23:05.110 回答
0

如果它不必很快,你可以使用 LINQ:

string clean = new String(tainted.Where(c => 0 <= "ABCDabcd1234:\r\n".IndexOf(c)).ToArray());
于 2011-03-14T19:18:25.393 回答