2013-08-01 78 views
2

我有文件名,其中可以有任意數量的單詞/空格。基本上,我需要正確的語法來消費字符串中間的任何字符而不消耗最後一個字。正則表達式捕獲文件名中的第一個/最後一個詞

一些問題背景 - 第一個單詞或最後一個單詞可能是我需要捕獲的日期。或者,最後一個詞可能是首字母縮寫。我需要指定捕獲組中的日期/首字母。

示例文件,

FileName          Expected Capture Groups 
--------          ---------------------- 
Myfile 120101.xls        Date: {Myfile, 120101} 
120101 MyFile.xls        Date: {Myfile, 120101} 
MyFile BHO.doc        Date: {Myfile} Initials: {BHO} 
120101 My file name BHO.docx     Date: {120101} Initials: {BHO} 
Foo.bar          None  
WhyDidIUsePeriods.huh.doc      None 
120101 WhyDidIUsePeriods.huh.doc    Date: {WhyDidIUsePeriods, 120101} 
WhyDidIUsePeriods BHO.huh.doc     Date: {WhyDidIUsePeriods} Initials: {BHO} 
120101 WhyDidIUsePeriods BHO.huh.doc   Date: {120101} Initials: {BHO} 

到目前爲止,我有以下的正則表達式:

@"^(?<Date>.+?(?=))?.*?((?<Initials>(?<=)[^0-9]*?)|(?<Date>(?<=).*?))?\..*?$" 

本工程爲兩個字長文件名,但不是什麼大(後組捕獲多個話)。問題是在第一個日期捕獲組之後的.*?。我需要這樣貪婪地捕捉所有「內部」詞彙而不消耗最後一個詞。我在考慮負向預測,但我不確定如何構建它,因此該模式既消耗所有字符,也不消耗匹配某個負向預測模式的字符(.*?\.)

(這是確定的日期捕捉組將捕獲非日期,所以定製以後分析邏輯爲)

是我想甚至有可能爲負先行?有更好的策略來滿足這些要求嗎?

編輯:

我說明什麼預期的結果將是每個文件旁邊的例子。我不想在日期中使用更具體的正則表達式,因爲它可能也是各種非數字格式。

不幸的是,正則表達式很有必要,因爲在某些情況下,有問題的.*?將被替換爲更具體的模式(例如,某些文件需要另外包含單詞「Foo」,正則表達式似乎是最好的工具) 。

+3

你可以從你的文件名發佈你的期望值嗎? – Angga

+0

你如何定義「單詞」?此外,文件名由1個或多個*段*組成('.')。當你說「找到第一個和最後一個單詞」時,這與文件名的分段結構有什麼關係?如果一個文件名由一個單詞組成,該怎麼辦? –

+0

可以假定文件名具有擴展名。我只關心第一部分(在任何時期之前)。一個詞由字符串,空格或句點的開始來界定。 – MgSam

回答

1

說明

此表達式將:

  • 假定唯一感興趣的數據從文件名中的第一個點
  • 假定縮寫是三個上的情況下,通過空間preceeded之前存在,和將會跟着一個點
  • 捕獲文件名的非首字母縮寫和非日期部分
  • 捕獲整個文件名直到但不包括t他第一個點
  • 捕獲的縮寫,如果他們存在
  • 捕捉如果存在
  • 允許日期,字母和文件,如果他們在文件名

爲此,我存在任何順序出現的日期「M使用

^ 
(?=(?:[^.]*?(?<file>(?<=^)[a-zA-Z\s]*?(?=\s[A-Z]{3}\.|\s)|(?<=\s)[a-zA-Z\s]*?(?=\.|\s[A-Z]{3}\.)))?) # get the file (aka not date and not initials 
(?=(?:[^.]*?\s(?<Initials>[A-Z]{3})\.)?)  # get the initials 
(?=(?:[^.]*?(?<Date>\d+))?) # capture the date value if it exists. 
(?=(?<FileName>.*?)\.)  # capture entire filename upto but not including the first dot 
.* 

enter image description here

Live Demo

示例文字

Myfile 120101.xls 
120101 MyFile.xls 
MyFile BHO.doc 
120101 My file name BHO.docx 
Foo.bar 
WhyDidIUsePeriods.huh.doc 
120101 WhyDidIUsePeriods.huh.doc 
WhyDidIUsePeriods BHO.huh.doc 
120101 WhyDidIUsePeriods BHO.huh.doc 

代碼

Regex re = new Regex(@"^(?=(?:[^.]*?(?<file>(?<=^)[a-zA-Z\s]*?(?=\s[A-Z]{3}\.|\s)|(?<=\s)[a-zA-Z\s]*?(?=\.|\s[A-Z]{3}\.)))?)(?=(?:[^.]*?\s(?<Initials>[A-Z]{3})\.)?)(?=(?:[^.]*?(?<Date>\d+))?)(?=(?<FileName>.*?)\.).*",RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline); 
MatchCollection mc = re.Matches(sourcestring); 

匹配

[0][0] = Myfile 120101.xls  
[0][file] = Myfile 
[0][Initials] = 
[0][Date] = 120101 
[0][FileName] = Myfile 120101 

[1][0] = 120101 MyFile.xls  
[1][file] = MyFile 
[1][Initials] = 
[1][Date] = 120101 
[1][FileName] = 120101 MyFile 

[2][0] = MyFile BHO.doc  
[2][file] = MyFile 
[2][Initials] = BHO 
[2][Date] = 
[2][FileName] = MyFile BHO 

[3][0] = 120101 My file name BHO.docx 
[3][file] = My file name 
[3][Initials] = BHO 
[3][Date] = 120101 
[3][FileName] = 120101 My file name BHO 

[4][0] = Foo.bar 
[4][file] = Foo 
[4][Initials] = 
[4][Date] = 
[4][FileName] = Foo 

[5][0] = WhyDidIUsePeriods.huh.doc  
[5][file] = WhyDidIUsePeriods 
[5][Initials] = 
[5][Date] = 
[5][FileName] = WhyDidIUsePeriods 

[6][0] = 120101 WhyDidIUsePeriods.huh.doc  
[6][file] = WhyDidIUsePeriods 
[6][Initials] = 
[6][Date] = 120101 
[6][FileName] = 120101 WhyDidIUsePeriods 

[7][0] = WhyDidIUsePeriods BHO.huh.doc  
[7][file] = WhyDidIUsePeriods 
[7][Initials] = BHO 
[7][Date] = 
[7][FileName] = WhyDidIUsePeriods BHO 

[8][0] = 120101 WhyDidIUsePeriods BHO.huh.doc 
[8][file] = WhyDidIUsePeriods 
[8][Initials] = BHO 
[8][Date] = 120101 
[8][FileName] = 120101 WhyDidIUsePeriods BHO 
+1

謝謝。這對幫助我找到正確的解決方案非常有幫助。我從來沒有見過在單獨的前瞻中進行所有比賽的技術,這非常有用。 – MgSam

相關問題