字符串分割忽略定界符之间的空值

3
我正在尝试使用Streamreader和Streamwriter将一些数据转换为SQL语句。
我的问题是,当我分割两个分隔符之间没有任何内容的行时,它们会被忽略,导致IndexOutOfRange错误。
因为我的temparray只有temparray [3],但它应该到temparray [6]。
如何分割和使用空值或用简单的字符替换这些空值,以便在创建SQL语句时不会出现IndexOutOfRange错误?
foreach (string a in values)
{
    int temp = 1;
    String[] temparray = a.Split(';');
    streamWriter.WriteLine("Insert into table Firma values({0},'{1}','{2}')", temp, temparray[1], temparray[4]);
    temp++;
}

2
你能举一个导致问题的字符串例子吗? - Oleksandr Kobylianskyi
4
不要这样构建 SQL 语句!这种方式容易受到注入攻击。类似这样的代码几乎是在恳求被黑客攻击。 - Joel Coehoorn
3
无法重现:"A;;;C".Split(';').Length 的结果为 4 - Heinzi
@user3107760 请在您的评论中加入一些措辞,说明您发布的字符串是一个示例输入,而不是德语中毫无意义的评论 :-) - Sergey Kalinichenko
8个回答

3
首先,这会带来麻烦(SQL注入)。你至少应该转义从字符串解析的值。
而且你似乎错了,因为String.Split默认情况下正是你想要的:`"x;y;;z".Split(';')`返回一个四元素数组`{"x", "y", "", "z"}`。你可以通过使用`StringSplitOptions.RemoveEmptyEntries`来实现所描述的行为:`"x;y;;z".Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries)`返回一个三元素数组`{"x", "y", "z"}`。这不是你想要的,正如你所说。
无论如何,在这里`"Überarbeitung der SAV Seite;b.i.b.;;;;PB;" .Split(';')`对我来说返回一个七元素数组,因此请检查你的输入和实现...

我甚至不知道什么是SQL注入,而且我认为这对我的小网站不会造成问题,它只是用来展示一些信息,没有更多的东西。 默认情况下,test1;;;;test2只对我显示test1和test2。 - user3107760
好的,我会尝试使用 RemoveEmptyEntries.None。这里怎么换行? - user3107760

1
如果您打印字符串,我相信它不会是您期望的结果。
static void Main(string[] args)
{
  var result = "Überarbeitung der SAV Seite;b.i.b.;;;;PB;".Split(';');

  foreach (var part in result)
  {
    Console.WriteLine(" --> " + part);
  }

  Console.ReadLine();
}

这很有用。它不会忽略空值。它会打印。
 --> Überarbeitung der SAV Seite
 --> b.i.b.
 -->
 -->
 -->
 --> PB
 -->

包括空值。
向Paderborn的bib问候 :)

0
如果您正在使用SQL Server,可以在查询中使用ISNULL运算符来返回空字符串而不是null。
例如:
SELECT ISNULL(PR_Arbeitstitel, '') FROM Table

0

为什么不迭代您的temparray以构建参数值字符串。

这并不完美,但应该指引您方向。

    foreach (string a in values)
    {
        int temp = 1;
        String[] temparray = a.Split(';');

        var stringBuilder = new StringBuilder();

        foreach (var s in temparray)
            stringBuilder.Append("'" + s + "',");

        var insertStatement = string.Format("Insert into table Firma values({0}, {1})", temp, stringBuilder.ToString().TrimEnd(','));

        temp++;
    }

0

我没有看到你所描述的问题。以下代码输出string[2]为string.Empty并且包含了全部5个元素。

        string[] str = "0,1,,3,4".Split(new char[] { ',' });
        foreach (string s in str)
        {
            Debug.Print(s);
        }

输出

0
1

3
4

0

我尝试使用你提供的字符串示例"Überarbeitung der SAV Seite;b.i.b.;;;;PB;"进行复现,但一切都正常。数组中有7个项目。 你可以尝试使用

string s = "Überarbeitung der SAV Seite;b.i.b.;;;;PB;";
var result = s.Split(new[] { ';' }, StringSplitOptions.None);

确保未启用StringSplitOptions.RemoveEmptyEntries

0
为什么会有两个分隔符挨在一起但它们之间没有任何内容?你不能控制输入吗?
如果是这种情况,你可以通过插入所谓的哨兵值来控制它,比如“IGNOREMEPLEASE”:
String[] temparray = a.Replace(";;", ";IGNOREMEPLEASE;").Split(';');

然后你的代码的其余部分就知道IGNOREMEPLEASE表示有一行是空的,应该被忽略。

话虽如此,但在向数据库发送数据时要非常小心,并清理用于构建SQL语句的传入数据,以消除任何危险因素。


输入来自Excel表格,不是我的。 - user3107760

-2
也许可以使用 ?? 运算符:
streamWriter.WriteLine(
    "Insert into table Firma values({0},'{1}','{2}')",
    temp,
    temparray[1] ?? 'x',
    temparray[4] ?? 'x');

然而,只有在您确定拆分后的输入至少有5个标记时,这仍然是安全的。如果您无法保证这一点,您需要将其包装在条件语句中:

if (temparray.Length < 5)
{
    // handle invalid input
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接