如何自动替换捕获组
本文关键字:替换 何自动 | 更新日期: 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();
}