.net正则表达式。仅在指定的捕获组内替换
是否可以使用.net正则表达式类对特定捕获组进行替换 比如说.net正则表达式。仅在指定的捕获组内替换,.net,regex,.net,Regex,是否可以使用.net正则表达式类对特定捕获组进行替换 比如说 <customer.*?(display="(?:yes|no)")?.*?> 我想在Customer xml元素上进行匹配,但在display attribute capture组中进行替换。我想这应该是第1组,但我总是可以命名它。我认为您需要捕获显示属性前后的内容 (<customer.*?)(display="(?:yes|no)")(.*?>) () 然后,您可以在替换lambda时使用它
<customer.*?(display="(?:yes|no)")?.*?>
我想在Customer xml元素上进行匹配,但在display attribute capture组中进行替换。我想这应该是第1组,但我总是可以命名它。我认为您需要捕获显示属性前后的内容
(<customer.*?)(display="(?:yes|no)")(.*?>)
()
然后,您可以在替换lambda时使用它
Regex.Replace(inputString, @"(<customer.*?)(display=""(?:yes|no)"")(.*?>)", m => String.Format("{0}{1}{2}", m.Groups[1], /* replacement string based on m.Groups[2] */, m.Groups[3]));
Regex.Replace(inputString,@“()”,m=>String.Format(“{0}{1}{2}”,m.Groups[1],/*基于m.Groups[2]*/,m.Groups[3]);
基于Andrews的回答,我创建了一个处理替换的方法,对其进行了一些扩展。在我的情况下,我想替换整个组,所以我创建了一个helper类来完成这个任务。此外,它不需要您创建捕获前和捕获后组来实现这一点
/// <summary>
/// A Regular Expression match and replace class
/// </summary>
public class RegexReplacer
{
private readonly int _captureGroupToReplace;
/// <summary>
/// Initialises the RegEx replacer with matching criteria.
/// </summary>
/// <param name="name">A name that identifies this replacement pattern</param>
/// <param name="matchCriteria">A regular Expression used to locate the values to replace</param>
/// <param name="replacementValue">The value that will replace the matched pattern</param>
/// <param name="captureGroupToReplace">The Capture group that should be replaced. The default is the entire match</param>
public RegexReplacer(string name, Regex matchCriteria, string replacementValue, int captureGroupToReplace = 0)
{
_captureGroupToReplace = captureGroupToReplace;
Name = name;
ReplacementValue = replacementValue;
MatchCriteria = matchCriteria;
}
public string Name { get; set; }
public Regex MatchCriteria { get; set; }
public string ReplacementValue { get; set; }
/// <summary>
/// Finds and replaces all instances of a string within the supplied string or replaces a group if the group id is supplied in the constructor
/// </summary>
public string ReplaceInString(string stringToSearch)
{
if (_captureGroupToReplace != 0)
return MatchCriteria.Replace(stringToSearch, new MatchEvaluator(ReplaceGroup));
return MatchCriteria.Replace(stringToSearch, ReplacementValue);
}
private string ReplaceGroup(Match match)
{
try
{
var matchedString = match.Value;
//Match index is based on the original string not the matched string
int groupIndex = match.Groups[_captureGroupToReplace].Index - match.Index;
int groupLength = match.Groups[_captureGroupToReplace].Length;
var preGroupString = matchedString.Substring(0, groupIndex);
var postGroupString = matchedString.Substring(groupIndex + groupLength, matchedString.Length - (groupIndex + groupLength));
var replacedString = String.Format("{0}{1}{2}", preGroupString, ReplacementValue, postGroupString);
return replacedString;
}
catch (Exception)
{
return match.Value;
}
}
}
//
///正则表达式匹配和替换类
///
公共类RegexReplacer
{
私有只读int_captureGroupToReplace;
///
///使用匹配条件初始化正则表达式替换程序。
///
///标识此替换模式的名称
///用于定位要替换的值的正则表达式
///将替换匹配图案的值
///应替换的捕获组。默认值为整个匹配
公共RegexReplacer(字符串名称、Regex匹配条件、字符串替换值、int captureGroupToReplace=0)
{
_captureGroupToReplace=captureGroupToReplace;
名称=名称;
ReplacementValue=ReplacementValue;
匹配标准=匹配标准;
}
公共字符串名称{get;set;}
公共正则表达式匹配条件{get;set;}
公共字符串替换值{get;set;}
///
///查找并替换所提供字符串中字符串的所有实例,或者如果构造函数中提供了组id,则替换组
///
公共字符串替换(字符串stringToSearch)
{
如果(_captureGroupToReplace!=0)
返回MatchCriteria.Replace(stringToSearch,新的MatchEvaluator(ReplaceGroup));
返回MatchCriteria.Replace(stringToSearch,ReplacementValue);
}
私有字符串替换组(匹配)
{
尝试
{
var matchedString=match.Value;
//匹配索引基于原始字符串,而不是匹配的字符串
int groupIndex=match.Groups[\u captureGroupToReplace].Index-match.Index;
int groupLength=match.Groups[\u captureGroupToReplace].Length;
var preGroupString=matchedString.Substring(0,groupIndex);
var postGroupString=matchedString.Substring(groupIndex+groupLength,matchedString.Length-(groupIndex+groupLength));
var replacedString=String.Format(“{0}{1}{2}”,preGroupString,ReplacementValue,postGroupString);
返回替换字符串;
}
捕获(例外)
{
返回match.Value;
}
}
}
我还必须修改我的原始模式,这样它会在xml末尾给我一个空组,以便在不存在属性的情况下插入一个属性(用法如图所示)
var replacer = new RegexReplacer("DisplayCustomerAttribute",
new Regex(@"(?:<customer\s.*?((\sdisplay=""(?:yes|no)"").*?|())>)"),
@" display=""yes""", 1)
xmlString = replacer.ReplaceInString(xmlString);
var replacer=new RegexReplacer(“DisplayCustomerAttribute”,
新正则表达式(@“(?:)”),
@“display=”“yes”“,1)
xmlString=replacer.ReplaceInString(xmlString);
另请注意,这是因为.net xml序列化在值与默认值相同时不包含属性。当您控制消费者时,这是可以的,但在我们的情况下,我们不是,因此我们需要明确。为什么不使用xml解析器?同意,但您需要摆脱第三个
?
。在最初的正则表达式中,它使捕获组成为可选的,这一点一开始就错了。(它永远不会捕获任何东西,不管显示属性是否存在。)在您得到它的地方,这是一个语法错误。@alanmore-Oops,感谢您的捕获。我没注意。现在修正了。我的实际答案有点不同,但我会给你这个想法的信用,看看我的答案,我是如何实现它的,我这样做的方式,你不需要事前和事后的小组