在字符串数组引用的字符串上设置字符串

本文关键字:字符串 设置 引用 数组 | 更新日期: 2023-09-27 18:27:25

string db;
ComboBox fieldBox = new ComboBox()
TextBox ValueBox = new TextBox()
ListBox dbValues = new ListBox()
private void LoadDB()
{
    //Structure
    string myStruct = "NAME'nAGE'nSEX'nSKILL
    db = "John't20'tMale'tNoob'n
                   Joe't20'tMale'tMedium'n
                   Jessica't27'tFemale'tExpert'n
                   John't21'tMale'tMedium
                  ";
    //Load struct to combobox
    string[] mbstr = myStruct.Split(''n');
    for (int i = 0; i < mbstr.Length; i++)
    {
        fieldBox.Items.Add(mbstr[i]);
    }
    string[] db2 = db.Split(''n');
    for (int i = 1; i < db2.Length - 1; i++)
    {
        //Display name and age in combobox
        dbValues.Items.Add(db2[i].Split(''t')[0] + " - " +   db2[i].Split(''t')[1]);
    }
}
void ValueBoxKeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode != Keys.Enter)
        return;
    db.Split(''n')[dbValues.SelectedIndex].Split(''t')[fieldBox.SelectedIndex] = valueBox.Text;
    MessageBox.Show("Value set: " +
                           db.Split(''n')[dbValues.SelectedIndex + 1].Split(''t')[fieldBox.SelectedIndex]
                            + " to " + valueBox.Text + ".");
}

这是它失败的地方:

db.Split(''n')[dbValues.SelectedIndex].Split(''t')[fieldBox.SelectedIndex] = valueBox.Text;

我尝试了这个,并尝试分配给数据库,但不起作用。我的原始字符串保持不变。

我不想转换为列表和字符串,我想直接更改。我该怎么做?

在字符串数组引用的字符串上设置字符串

你的第一个问题是你的字符串:除非你使用 @ escaping,否则你不能让你的字符串跨越多行,如果你使用 @ escaping,你不能做 ''t 或 ' 并保留它们的转义符和换行符的含义。

第二个问题是对.NET字符串的根本误解,字符串是不可变的。拆分将创建一个数组,没有对原始字符串的引用,或者拆分的第二个数组。您需要执行以下操作:

[TestClass]
public class StringTest
{
    public TestContext TestContext { get; set; }
    [TestMethod]
    public void RewriteString()
    {
        var str = "Garry't19'tMale'tNoob'n" +
            "Joe't25'tMale'tMedium'n" +
            "Gary't33'tFemale'tExpert";
        var rows = str.Split(''n');
        var columns = rows[0].Split(''t');
        columns[0] = "Jerry";
        rows[0] = string.Join("'t", columns);
        str = string.Join("'n", rows);
        TestContext.WriteLine(str);
    }
}
 Test Name: RewriteString
 Test Outcome:  Passed
 Result StandardOutput: TestContext Messages:
 Jerry  19  Male    Noob
 Joe    25  Male    Medium
 Gary   33  Female  Expert

真的希望有一种更简单的方法可以做到这一点,可能是使用正则表达式吗?

现在真正看看你的(新(问题。我已经完全重构了您拥有的内容,因为我不知道您的数据情况,我不完全确定使用字符串作为数据库是一个好主意:(由于使用了动态,这将在没有任何引用的情况下编译(。

public class SomeView
{
    string db;
    dynamic fieldBox = null;
    dynamic valueBox = null;
    dynamic dbValues = null;
    dynamic MessageBox = null;
    private void LoadDB()
    {
        //Structure
        string myStruct = "NAME'nAGE'nSEX'nSKILL";
        db = "John't20'tMale'tNoob'n" +
                       "Joe't20'tMale'tMedium'n" +
                       "Jessica't27'tFemale'tExpert'n" +
                       "John't21'tMale'tMedium";
        //Load struct to combobox
        string[] mbstr = myStruct.Split(''n');
        for (int i = 0; i < mbstr.Length; i++)
        {
            fieldBox.Items.Add(mbstr[i]);
        }
        string[] db2 = db .Split(''n');
        for (int i = 1; i < db2.Length - 1; i++)
        {
            var data = db2[i].Split(''t'); //expensive only do once
            //Display name and age in combobox
            dbValues.Items.Add(data[0] + " - " + data[1]);
        }
    }
    protected string Transform(string value, int row, int column, string replacement, out string old)
    {
        var rows = value.Split(''n');
        var columns = rows[row].Split(''t');
        old = columns[column];
        columns[column] = replacement;
        rows[row] = string.Join("'t", columns);
        return string.Join("'n", rows);
    }
    void ValueBoxKeyDown(object sender, dynamic e)
    {
        if (e.KeyCode != "enter")
            return;
        string old;
        string newValue = this.Transform(db, dbValues.SelectedIndex, fieldBox.SelectedIndex, valueBox.Text, out old);
        MessageBox.Show("Value set: " + old + " to " + valueBox.Text + ".");
    }
}

所以这样更好:

public class SomeView
{
    dynamic fieldBox = null;
    dynamic valueBox = null;
    dynamic dbValues = null;
    dynamic MessageBox = null;
    private List<Person> People = new List<Person>();
    private void LoadDB()
    {
        //Structure
        string myStruct = "NAME'nAGE'nSEX'nSKILL";
        string db = "John't20'tMale'tNoob'n" +
                       "Joe't20'tMale'tMedium'n" +
                       "Jessica't27'tFemale'tExpert'n" +
                       "John't21'tMale'tMedium";
        //Load struct to combobox
        string[] mbstr = myStruct.Split(''n');
        for (int i = 0; i < mbstr.Length; i++)
        {
            fieldBox.Items.Add(mbstr[i]);
        }
        People.Clear();
        foreach(var row in db.Split(''n'))
        {
            var columns = row.Split(''t');
            Person p = new Person();
            p.Name = columns[0];
            p.Age = int.Parse(columns[1]);
            p.Sex = (Person.Sexs)Enum.Parse(typeof(Person.Sexs), columns[2]);
            p.SkillLevel = (Person.SkillLevels)Enum.Parse(typeof(Person.SkillLevels), columns[2]);
            People.Add(p);
            dbValues.Items.Add(string.Format("{0}-{1}", p.Name, p.Age);
        }
    }
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public enum Sexs
        {
            Male,
            Female
        }
        public Sexs Sex { get; set; }
        public enum SkillLevels
        {
            Noob,
            Medium,
            Expert
        }
        public SkillLevels SkillLevel { get; set; }
    }
    void ValueBoxKeyDown(object sender, dynamic e)
    {
        if (e.KeyCode != "enter")
            return;
        Person p = this.People[dbValues.SelectedIndex];
        switch((int)fieldBox.SelectedIndex)
        {
            case 0: p.Name = valueBox.Text; break;
            case 1: p.Age = int.Parse(valueBox.Text); break;
            case 2: p.Sex = (Person.Sexs)Enum.Parse(typeof(Person.Sexs), valueBox.Text); break;
            case 3: p.SkillLevel = (Person.SkillLevels)Enum.Parse(typeof(Person.SkillLevels), valueBox.Text); break;
            default: throw new NotImplementedException();
        }
        MessageBox.Show("Value set: " + old + " to " + valueBox.Text + ".");
    }
}

然而,这仍然是垃圾,因为如果你有一个强类型的数据集,你实际上可以将其绑定到表单控件,而无需直接操作项目。https://msdn.microsoft.com/en-US/library/C8aebH9k(v=vs.110(.aspx

不能更改返回字符串的方法的返回值,因为字符串是不可变的。您可以执行的操作如下:

string myDatabase = 
    "Garry't19'tMale'tNoob'n" +
    "Joe't25'tMale'tMedium'n" +
    "Gary't33'tFemale'tExpert";
var tmp = "";
foreach(var line in myString.Split(''n')) {
    tmp = tmp + Regex.Replace(line, "^.*?(?=''t)", myReplaceText);
}
myString = tmp;

此正则表达式将搜索每行中第一个选项卡之前的所有内容,将其替换为"Jerry"并将每个替换的行连接成myString