簡體   English   中英

正則表達式捕獲文件名中的第一個/最后一個單詞

[英]Regex capture first/last word in a filename

我的文件名中可以​​包含任意數量的單詞/空格。 基本上,我需要正確的語法來消耗字符串中間的任何字符,而不消耗最后一個單詞。

一些問題背景-第一個單詞或最后一個單詞可能是我需要記錄的日期。 或者,最后一個單詞可以是縮寫。 我需要命名捕獲組中的日期/縮寫。

示例文件

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”一詞,Regex似乎是最好的工具)。

描述

該表達式將:

  • 假定文件名中唯一有趣的數據在第一個點之前
  • 假定首字母為三個大寫字母,以空格開頭,后跟一個點
  • 捕獲文件名的非首字母和非日期部分
  • 捕獲整個文件名,但不包括第一個點
  • 捕獲縮寫(如果存在)
  • 捕獲日期(如果存在)
  • 如果文件名中存在日期,首字母和文件,則它們可以按任何順序顯示

為此,我正在使用

^
(?=(?:[^.]*?(?<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
.*

在此處輸入圖片說明

現場演示

示范文本

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

暫無
暫無

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

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