如何自动替换捕获组

本文关键字:替换 何自动 | 更新日期: 2023-09-27 18:28:32

假设我有一个与特定文件模式匹配的源文件,并且我希望在新创建的目标文件中重用该文件模式的某些元素
例如,regex中给出的指定文件模式是

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指定了多少个捕获组,所以如何自动化所有这些?这个是否有其他方式或一些智能的本机函数性

如何自动替换捕获组

尝试

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,使用^$来强制正则表达式考虑整个字符串,(?=_FOO.xml$)表示"followed by _FOO(end of the string)",但这不是一个捕获组。

如果你能让他们使用命名的组(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";  
  • 因此,我们使用正则表达式并提供一些示例数据
  • 对于mockMatches中的每个匹配,您将用拉入文件名列表的枚举器来替换它
  • 然后,我们使用src_pattern匹配regex,并启用忽略大小写
  • 那么我们想要作为GroupCollection出现的匹配组,所以我们Cast<T>()可以枚举为IEnumerable<Group>
  • 使用Skip(1)跳过第一组(即整个匹配)
  • 然后用.Select(a=>a.Value)得到组的值(组匹配的实际文本)
  • 使用_作为.Aggregate((s1,s2)=>s1+"_"+s2)的分隔符将所有这些连接在一起
  • 则添加文件结束常数CCD_ 15

基于Linqpad的答案:

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();
}