求助:编写正则表达式匹配XML中非DataMember属性内的$$包裹内容
解决方案:匹配$$包裹内容并排除DataMember属性内的项
首先我完全理解你的困扰——想精准匹配$$...$$格式的占位符,却总是误抓到属性间的内容,还没法排除DataMember里的目标。之前的正则没到位是因为没准确界定“在DataMember属性范围内”这个条件,现在给你一个能直接用的方案:
正确的正则表达式
(?<!DataMember="[^"]*)\$\$(.*?)\$\$(?![^"]*")
正则逻辑拆解
(?<!DataMember="[^"]*):负向后行断言,确保当前的$$前面,不会出现DataMember="加一串非引号字符(也就是还没走到属性值的结束引号),直接排除DataMember属性值开头到中间的$$。\$\$(.*?)\$\$:核心匹配部分,用非贪婪模式精准捕捉单个$$包裹的内容,避免跨多个占位符误匹配。(?![^"]*"):负向前行断言,确保当前的$$后面,不会出现一串非引号字符加结束引号(也就是还没走出DataMember的属性值范围),把DataMember属性值中间到结尾的$$也排除掉。
实际测试效果
拿你的XML文本测试:
<MyXMLTag DataMember="$$Date$$" Name="$$DateName$$" DateTimeGroupInterval="MonthYear" DefaultId="$$MyId$$" /> <NameTag>$$item$$</NameTag>
最终匹配结果为:$$DateName$$、$$MyId$$、$$item$$,而$$Date$$(位于DataMember属性内)会被精准排除,完全符合你的需求。
C#替换示例(适配你的写法)
看你用了@符号,推测是在C#环境中使用,这里给个替换占位符的代码示例:
string xmlInput = @"<MyXMLTag DataMember=""$$Date$$"" Name=""$$DateName$$"" DateTimeGroupInterval=""MonthYear"" DefaultId=""$$MyId$$"" /> <NameTag>$$item$$</NameTag>"; string regexPattern = @"(?<!DataMember=""[^""]*)\$\$(.*?)\$\$(?![^""]*"")"; // 替换占位符为自定义内容 string result = Regex.Replace(xmlInput, regexPattern, match => { string placeholder = match.Groups[1].Value; return placeholder switch { "DateName" => "自定义日期名称", "MyId" => "ID_2024001", "item" => "自定义条目内容", _ => match.Value // 未知占位符保持原样 }; });
之前的正则失效原因
你之前的写法比如(?<!^\bDataMember="\b)存在两个关键问题:
^\b错误限定了DataMember必须在文本开头,不符合实际XML结构的多样性;- 没有考虑属性值的结束引号,导致正则把属性间的引号和文本错误识别成了占位符的一部分。
内容的提问来源于stack exchange,提问作者João Martins
相关产品推荐
相关产品推荐

