0

假设我有一个与某个文件模式匹配的源文件,并且我希望在新创建的目标文件中重用文件模式的某些元素。
所以对于前。正则表达式中给出的指定文件模式是

src_pattern = "(\d\d)_(\d\d)_(\d\d\d\d)_FOO.xml";

after searching a directory, found a matching source file looking like 

src = 08_21_2013_foo.xml

now the new file must be of the form 

dst = $3$1$2_BAR.xml;  

捕获组从源中提取的位置(看起来像 20130821_BAR.xml)。我将如何高效地完成这项工作,需要非常灵活,而且我不知道它们中的每一个是什么样的,它们是从其他地方拉出来的。所以我想我在提取捕获组的编号时遇到了麻烦,即第 3 个、第 1 个、第 2 个,假设我找到了它,我如何将它引用回源文件。我是否必须有一个表示数字的整数(比如 k)并像引用它一样引用它

match = Regex.Match(src, src_pattern)
match.Groups[k].Value

拉这些数字似乎很痛苦......

我也不知道每个 dst 指定了多少这些捕获组,那么如何自动化所有这些呢?是否有另一种方法或一些智能的本机功能

4

3 回答 3

1
  • So we take the regex and provide some sample data.
  • for each match in mockMatches which you would replace with the enumerator that pulls in your list of filenames.
  • we then match the regex using the src_pattern with ignore case turned on.
  • then we want the matching groups which comes out as a GroupCollection so we Cast<T>() that Enumerable as IEnumerable<Group>
  • skip the first group (which is the entire match) using Skip(1)
  • then get the group's value (the actual text of the group match) with .Select(a=>a.Value)
  • join all of those together using a _ as the seperator with .Aggregate((s1,s2)=>s1+"_"+s2)
  • then add the file ending constant "_bar.xml"

Linqpad based answer:

var src_pattern= @"(\d\d)_(\d\d)_(\d\d\d\d)_FOO\.xml";
var mockMatches = new[]{"08_21_2013_foo.xml"};
foreach(var mm in mockMatches){
  var match = Regex.Match(mm,src_pattern, RegexOptions.IgnoreCase).Dump();
  var dst= match.Groups.Cast<Group>().Skip(1).Select(a=>a.Value).Aggregate((s1,s2)=>s1+"_"+s2)+"_bar.xml";
  dst.Dump();
}
于 2013-08-21T13:56:29.507 回答
1

如果您可以让他们使用命名组(http://msdn.microsoft.com/en-us/library/bs2twtah.aspx#named_matched_subexpression),您可以轻松地根据他们的要求运行替代品并让他们命名再次在结果输出 dst 中。例如:

src_pattern = "(<first>\d\d)_(<second>\d\d)_(<third>\d\d\d\d)_FOO.xml";

after searching a directory, found a matching source file looking like 

src = 08_21_2013_foo.xml

now the new file must be of the form 

dst = "[third][first][second]_BAR.xml";  
于 2013-08-21T13:56:55.283 回答
1

尝试

var rx = new Regex(@"^(\d\d)_(\d\d)_(\d\d\d\d)(?=_FOO\.xml$)", RegexOptions.IgnoreCase);
var res = rx.Replace("08_21_2013_foo.xml", "$3$1$2");

注意RegexOptions.IgnoreCase, 的使用^and$强制正则表达式考虑整个字符串,而(?=_FOO.xml$)这意味着"followed by _FOO(end of the string)",但这不是一个捕获组。

于 2013-08-21T13:55:02.280 回答