我有一系列需要去标记的字符串。字符串来自数据库,看起来像这样
Subject: Ticket ##TicketID## Created
ShortText: Ticket ##TicketName## created (ID: ##TicketID##).
LongText: <a href="##BaseUrl##/Ticket/Details/##TicketID##">##TicketName##</a> was created on ##CreatedOn##.
每个标记都是相关事件对象的属性名称,基于某些操作触发。例如,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; }
}
我能够根据对象动态创建字典,将属性名称映射到value,从而找到/解决问题。我还能够在Regex.Replace调用上取得一些进展。替换主题字符串中的标记可以很好地使用:
Regex.Replace(templates.Subject, @"##(.*)##", match => map[match.Groups[1].Value]);
然而,它在ShortText或LongText上的效果并不好。从我可以从异常抛出的东西中可以看出,Regex匹配太多了。而不是匹配
##TicketName##
来自字符串,它正在尝试匹配
##TicketName## created (ID: ##TicketID##
显然,我希望单独匹配每个令牌。我认为这是我的错误,但我错过了什么?
答案 0 :(得分:9)
.*
贪婪且尽可能多地匹配,包括干预##
s。
您有三种选择:
@"##(.*?)##"
。工作方式相同,但现在.*?
将匹配尽可能少的字符。对于大多数情况,这应该没问题。#
s:##
之间@"##([^#]*)##"
##hello#there##
。但是,这意味着##
将无法匹配。##
s:@"##((?:(?!##).)*)##"
之间不允许##hello#there##
。这允许{{1}}。这对于当前的应用程序来说可能有点过头了,但它会在更复杂的情况下有所帮助,例如在处理嵌套结构时。使用其中任何一个最清楚地传达您的意图。