簡體   English   中英

從字符串中獲取字符的首次出現

[英]Get first occurence of a char from a string

首先,我想指出的是,期望的結果是一個char,而不是它的位置索引(int)。
我試圖為用戶提供選擇所需日期格式的選項,因此,我創建了2個comboBoxes: 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;

當用戶選擇其他分隔符時,它必須反映在另一個comboBox中,因為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);
    }
}

選擇的日期格式以后會保存到數據庫中,所以我想我也可以添加另一個用於存儲分隔符的字段,但我不想這樣做。 如您所見,上面的代碼包含??? 在里面。 所以,問題是:我該如何用能找到分隔符的代碼替換這些問號?

在絕對必須進行字符串搜索的極少數情況下,您可以執行以下操作:

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);
    }
}

假設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個或多個出現的任何字符,?:表示模式搜索匹配開始並且期望字符被傳遞(此處為“ 。”)(為了避免對特殊字符(如。,* 、?等)進行特殊處理),將對所有數據進行搜索,否則將在第一次出現時返回true,否則返回false。

編輯2:

為了提供正則表達式潛在的_dateFormatsList ,您可以在_dateFormatsList使用多種日期格式,但是所有解決方案都只需選擇一個值來找出運算符,其他值又如何,如果數據損壞並且不止一個,該怎么辦?存在分隔符,以下代碼將解決許多此類問題,並且可以通過更改模式進一步嚴格:

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

它代表所有的日期格式包含分隔符-但不是. / ,在分隔符之前還有一個數字(\\ d)重復-,需要使用Linq All運算符來應用此模式,如下所示:

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

這只是為了描述正則表達式的功能,其他解決方案無法幫助實現這一點,我認為大多數人由於對模式創建缺乏了解而發現正則表達式很復雜

首先,我想遵循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]);
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM