Regex.Replace行为奇怪

Woo*_*460 2 c# regex

我有一系列字符串,我需要去标记.字符串来自数据库,看起来像这样

Subject: Ticket ##TicketID## Created
ShortText: Ticket ##TicketName## created (ID: ##TicketID##).
LongText: <a href="##BaseUrl##/Ticket/Details/##TicketID##">##TicketName##</a> was created on ##CreatedOn##.
Run Code Online (Sandbox Code Playgroud)

每个标记都是相关事件对象的属性名称,基于某些操作触发.例如,TicketCreatedEvent对象可能看起来像

public class TicketCreatedEvent : ILAMPEvent {
    public Guid TicketID { get; set; }
    public string TicketName { get; set; }
    public DateTime CreatedOn { get; set; }
    public string BaseUrl { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我能够根据对象动态创建字典,将属性名称映射到值,从而找到/解决问题.我还能够在Regex.Replace调用上取得一些进展.替换主题字符串中的标记可以很好地使用:

Regex.Replace(templates.Subject, @"##(.*)##", match => map[match.Groups[1].Value]);
Run Code Online (Sandbox Code Playgroud)

但是,它在ShortText或LongText上的工作效果并不好.从我可以从异常抛出的东西中可以看出,Regex匹配太多了.而不是匹配

##TicketName## 
Run Code Online (Sandbox Code Playgroud)

从字符串,它试图匹配

##TicketName## created (ID: ##TicketID##
Run Code Online (Sandbox Code Playgroud)

显然,我希望单独匹配每个令牌.我认为这是我的错误,但我错过了什么?

Tim*_*ker 9

.*是贪婪和尽可能多的匹配,包括干预##.

你有三个选择:

  1. 使用惰性量词:@"##(.*?)##".工作原理相同,但现在.*?将匹配尽可能少的字符.对于大多数情况,这应该没问题.
  2. 具体是不允许#s 介入##s : @"##([^#]*)##". 但是,这意味着##hello#there##不匹配.
  3. 更具体些,不允许##s之间##S: @"##((?:(?!##).)*)##".这允许##hello#there##.这对于当前的应用程序来说可能有点过头了,但它会在更复杂的情况下提供帮助,例如在处理嵌套结构时.

使用其中任何一个最清楚地表达您的意图.