从字符串中首次出现char

时间:2017-01-13 10:54:09

标签: c# replace

首先,我想指出所需的结果是一个字符,而不是它的位置索引(int)。
我试图让我的用户选择他们想要的日期格式,因此,我创建了2个组合框:comboBox_DateFormatDivider用户在点,破折号和斜线之间选择;和comboBox_DateFormat用户选择日期格式的地方。 comboBox_DateFormat包含List<string>,如下所示:

_dateFormatsList = new List<string>()
{
    "d-M-yy (" + DateTime.Now.ToString("d-M-yy") + ")",
    "dd-M-yy (" + DateTime.Now.ToString("dd-M-yy") + ")",
    "d-MM-yy (" + DateTime.Now.ToString("d-MM-yy") + ")",
    "dd-MM-yy (" + DateTime.Now.ToString("dd-MM-yy") + ")",
    "d-M-yyyy (" + DateTime.Now.ToString("d-M-yyyy") + ")",
    "dd-M-yyyy (" + DateTime.Now.ToString("dd-M-yyyy") + ")",
    "d-MM-yyyy (" + DateTime.Now.ToString("d-MM-yyyy") + ")",
    "dd-MM-yyyy (" + DateTime.Now.ToString("dd-MM-yyyy") + ")",
    "yy-M-d (" + DateTime.Now.ToString("yy-M-d") + ")",
    "yy-M-dd (" + DateTime.Now.ToString("yy-M-dd") + ")",
    "yy-MM-d (" + DateTime.Now.ToString("yy-MM-d") + ")",
    "yy-MM-dd (" + DateTime.Now.ToString("yy-MM-dd") + ")",
    "yyyy-M-d (" + DateTime.Now.ToString("yyyy-M-d") + ")",
    "yyyy-M-dd (" + DateTime.Now.ToString("yyyy-M-dd") + ")",
    "yyyy-MM-d (" + DateTime.Now.ToString("yyyy-MM-d") + ")",
    "yyyy-MM-dd (" + DateTime.Now.ToString("yyyy-MM-dd") + ")"
};
comboBox_DateFormat.DataSource = _dateFormatsList;

当用户选择不同的分隔符时,它必须反映在另一个组合框中,因此DateFormat依赖于DateFormatDivider,因此必须在运行时更改其内容。以下是代码(和问题):

private void comboBox_DateFormatDivider_SelectedIndexChanged(object sender, EventArgs e)
{
    for (int i = 0; i < _dateFormatsList.Count; i++)
    {
        _dateFormatsList[i] = _dateFormatsList[i].Replace(_dateFormatsList[i].???.ToString(), comboBox_DateFormatDivider.SelectedText);
    }
}

选择的日期格式稍后会保存到数据库中,所以我想我还可以添加另一个存储分隔符的字段,但我不想这样做。如您所见,上面的代码中包含???。所以,问题是:如何用代码找到我包含的分隔符代替这些问号?

3 个答案:

答案 0 :(得分:2)

在绝对必须进行字符串搜索的极少数情况下,您可以执行以下操作:

string[] separators = new string[] { "-", ".", "/" };

void DetectCurrentSeparator(string dbDateFormat)
{
    for (int i = 0; i < separators.Length; i++)
    {
        if (dbDateFormat.IndexOf(separators[i]) >= 0)
        {
            // Assuming the above array corresponds with the order of the divider combobox
            combobox_DateFormatDivider.SelectedIndex = i;
            break;
        }
    }
}

现在已经说过,这个方法应该只需要在程序的生命周期中使用一次 - 首先从数据库中检索日期格式。在剩下的时间里,没有理由使用任何字符串搜索。您已经从组合框中获得了所需的分隔符,因此不要试图弄清楚现有的分隔符是什么,而是使用一个公共临时字符,然后替换它。

初始化如下:

DateTime now = DateTime.Now;
_dateFormatsMasterList = new List<string>()
{
    "d@M@yy (" + now.ToString("d@M@yy") + ")",
    "dd@M@yy (" + now.ToString("dd@M@yy") + ")",
    "d@MM@yy (" + now.ToString("d@MM@yy") + ")",
    "dd@MM@yy (" + now.ToString("dd@MM@yy") + ")",
    "d@M@yyyy (" + now.ToString("d@M@yyyy") + ")",
    "dd@M@yyyy (" + now.ToString("dd@M@yyyy") + ")",
    "d@MM@yyyy (" + now.ToString("d@MM@yyyy") + ")",
    "dd@MM@yyyy (" + now.ToString("dd@MM@yyyy") + ")",
    "yy@M@d (" + now.ToString("yy@M@d") + ")",
    "yy@M@dd (" + now.ToString("yy@M@dd") + ")",
    "yy@MM@d (" + now.ToString("yy@MM@d") + ")",
    "yy@MM@dd (" + now.ToString("yy@MM@dd") + ")",
    "yyyy@M@d (" + now.ToString("yyyy@M@d") + ")",
    "yyyy@M@dd (" + now.ToString("yyyy@M@dd") + ")",
    "yyyy@MM@d (" + now.ToString("yyyy@MM@d") + ")",
    "yyyy@MM@dd (" + now.ToString("yyyy@MM@dd") + ")"
};

_dateFormatsList = new List<string>(_dateFormatsMasterList);
comboBox_DateFormat.DataSource = _dateFormatsList;

您的SelectionChanged事件如此:

private void comboBox_DateFormatDivider_SelectedIndexChanged(object sender, EventArgs e)
{
    for (int i = 0; i < _dateFormatsList.Count; i++)
    {
        _dateFormatsList[i] = _dateFormatsMasterList[i].Replace("@", comboBox_DateFormatDivider.SelectedText);
    }
}

答案 1 :(得分:1)

假设Date格式的分隔符数量是有限的,我将执行以下操作:

List<string> dividers = new List<string>{".","/","-"}

private void comboBox_DateFormatDivider_SelectedIndexChanged(object sender, EventArgs e)
{
    string currentSeparator = string.Empty;

     foreach(var s in dividers)
     {
     string pattern = @".*(?:\" + s + ").*";

        if(Regex.IsMatch(_dateFormatsList[0],pattern))
        {
          currentSeparator = s;
          break;    
         }    
     }
    for (int i = 0; i < _dateFormatsList.Count; i++)
    {
        _dateFormatsList[i] = _dateFormatsList[i].Replace(currentSeparator, comboBox_DateFormatDivider.SelectedText);
    }
}

修改1:

关于正则表达式的说明:

以下是详细信息: ".*(?:\.).*", 。*表示任何出现0或更多字符的任何字符, ?:指模式搜索匹配开始,它期望传递的字符(这里&#34;。&#34;),(转义,以避免特殊字符的特殊处理,如。,*,?等)在所有数据中搜索它将在第一次出现时返回true,否则为false。

编辑2:

为了提供正则表达式的潜力示例,在_dateFormatsList中,您有多种日期格式,但所有解决方案,只需选择一个值来计算运算符,其他值如何,如果存在数据损坏和多个分隔符,代码将处理许多此类问题,并可通过更改模式进一步严格:

string pattern = @"^(?!\.\/)[\d]{1,4}[\-][\d]{1,2}[\-][\d]{1,4}$";

它代表所有包含分隔符-但不包含./的日期格式,还有一个数字(\ d)重复,在分隔符之前 - ,这需要使用Linq All运算符应用模式,如下所示:

bool result = _dateFormatsList.All(data => Regex.IsMatch(data,pattern));

这只是为了描述正则表达式的强大功能,其他解决方案无法帮助实现,我认为大多数人都会因为对模式创建缺乏了解而发现正则表达式复杂

答案 2 :(得分:0)

首先,我想与Abion47的建议一起使用变量来存储日期并在列表中使用它。

然后你可以这样做

char x = _dateFormatsList[0][1];
        for (int i = 0; i < _dateFormatsList.Count; i++)
            {
                _dateFormatsList[i] = _dateFormatsList[i].Replace(x, comboBox_DateFormatDivider.SelectedItem.ToString()[0]);
            }