我的文件名可以包含任意数量的单词/空格。基本上,我需要正确的语法来消耗字符串中间的任何字符而不消耗最后一个字。
一些问题背景 - 第一个单词或最后一个单词可能是我需要捕获的日期。或者,最后一个单词可以是首字母。我需要命名捕获组中的日期/首字母。
示例文件,
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”,正则表达式似乎是最好的工具)。
答案 0 :(得分:1)
此表达式将:
为此,我正在使用
^
(?=(?:[^.]*?(?<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