2016-01-04 237 views
2

我有一個不尋常的項目,我需要在第二個字符「\」出現後檢索文本,實際上給了我最後兩個目錄下面的例子字符串:獲取第二個字符/字符串出現的字符串

  • d:\存檔目錄\ 2015年12月31日下午\ SerialNo_01
  • d:\存檔目錄\ 2016年1月1日\ SerialNo_02
  • d:\存檔目錄\一月2016 \ SerialNo_03

期望的結果是,分別爲:

  • 2015年12月31日下午\ SerialNo_01
  • 2016年1月1日\ SerialNo_02
  • 2016年1月\ SerialNo_03

我想盡可能幹淨地完成此操作,並且最好在每個字符串的一行代碼中進行。

在Stack Overflow上找不到任何有關c#中字符串或字符串中字符串或字符的倒數第二次出現(或者,對於第N次出現倒退)的問題,我正在回答這個問題。如果社區發現這個問題是重複的,或者認爲這個問題太不明確,我願意刪除它。

編輯:澄清,我不需要做這個作爲字符串列表;他們將一次運行一個。我將它們作爲單選按鈕控件動態添加到表單中。

+0

如果感興趣的正則表達式,['\\ [^ \\] + \\ $'(*)(https://開頭帶有'gm'標誌的regex101.com/r/cB7cE4/1)。 – Tushar

回答

3

你不需要正則表達式,你可以依賴由.NET處理提供內置的路徑上。

var input = new List<string> { 
    @"D:\Archive Directory\2015-12-31 PM\SerialNo_01", 
    @"D:\Archive Directory\2016-01-01\SerialNo_02", 
    @"D:\Archive Directory\January 2016\SerialNo_03" 
}; 

var result = input.Select(s => Path.Combine(Directory.GetParent(s).Name, Path.GetFileName(s))); 

產量:

2015-12-31 PM\SerialNo_01 
2016-01-01\SerialNo_02 
January 2016\SerialNo_03 

那麼你也沒必要擔心邊緣的情況下,甚至可以跨操作系統的兼容性。

+0

如果「SerialNo_0x」部分是目錄而不是文件,這是否仍然有效?由於某些原因,即使我將'Path.GetFileName(s)'改爲'Path.GetDirectoryName(s)'時,它也不會編譯;在's'的兩個引用中,我都收到了「無法將字符串轉換爲字符串」錯誤。 –

+0

我正在分別使用每個路徑(不是以逗號分隔的列表),但我不認爲這會是問題? –

+0

它不知道它是否是一個目錄或文件,但上述內容適用於兩者。錯誤是因爲你可能使用輸入作爲字符串,而不是字符串列表 – Rob

1

我從this clever answer調整了代碼後能夠想出一個解決方案。

myString.Split('\\').Reverse().Take(2).Aggregate((s1, s2) => s2 + "\\" + s1); 

這將在每個反斜槓分割字符串,然後反轉得到的字符串數組和連接它們放回在一起之前採取僅僅最後兩個元件,現在以相反的順序,賦予所期望的結果。

+2

這是一個非常浪費的方式來獲取子字符串... Regular LastIndexOf更快,並不會產生瘋狂的字符串/對象的過程中。 –

+0

同意 - 這是我嘗試的第一件事,但我不尋找反斜槓的最後一個索引,我正在尋找倒數第二個索引。你能告訴我你將如何使用LastIndexOf來做到這一點? –

+1

我會在SO問題上發佈問題「是否有LastIndexOf可以從給定的位置開始向後搜索......」也許有人會爲我搜索MSDN並給出答案。比尋找像http://stackoverflow.com/questions/2571716/find-nth-occurrence-of-a-character-in-a-string和複製粘貼前進的答案。 –

1

你也可以匹配你想要的部分。

(?<=\\)[^\\]*\\[^\\]*$ 

查看演示。

https://regex101.com/r/fM9lY3/56

string strRegex = @"(?<=\\)[^\\]*\\[^\\]*$"; 
Regex myRegex = new Regex(strRegex, RegexOptions.Multiline); 
string strTargetString = @"D:\Archive Directory\2015-12-31 PM\SerialNo_01" + "\n" + @"D:\Archive Directory\2016-01-01\SerialNo_02" + "\n" + @"D:\Archive Directory\January 2016\SerialNo_03"; 

foreach (Match myMatch in myRegex.Matches(strTargetString)) 
{ 
    if (myMatch.Success) 
    { 
    // Add your code here 
    } 
} 
0
If you still want to use Regex, you can use 

Match match = Regex.Match(inputString,@".:\\.*\\(.*\\.*)"); 

if(match.success) 
{ 
Result = match.Groups[1].value; 
} 

The first group in match will give the required result 

對於多個結果的使用匹配,而不是匹配

0
List<string> paths = new List<string> { 
        @"D:\Archive Directory\2015-12-31 PM\SerialNo_01", 
        @"D:\Archive Directory\2016-01-01\SerialNo_02", 
        @"D:\Archive Directory\January 2016\SerialNo_03" }; 

var requiredPaths = paths.Select(item=> string.Join(@"\",item.Split('\\'). 
           Reverse().Take(2).Reverse())); 
相關問題