var regex = new Regex(@"{([A-z]*)(([^]|:)((\\:)|[^:])*?)(([^]|:)((\\:)|[^:])*?)}");
表达式[粗略]旨在使用以下格式查找输入中的标记:{name[:pattern[:format]]}
,其中pattern
和format
是可选的。
{
([A-z]*) // name
(([^]|:)((\\:)|[^:])*?) // regex pattern
(([^]|:)((\\:)|[^:])*?) // format
}
此外,表达式尝试忽略转义的冒号,从而允许使用{Time:\d+\:\d+\:\d+:hh\:mm\:ss}
等字符串
在RegExr.com上进行测试时,一切都充分,但是当在C#中尝试相同的模式时,输入无法匹配,为什么?
(对表达式进行一般性改进的任何建议也非常受欢迎)
答案 0 :(得分:6)
[^]
模式仅在JavaScript中与而不是匹配,即任何字符都有效(尽管在ES5中,它与BMP平面外的字符不匹配)。在C#中,可以很容易地将任何字符与.
匹配并传递RegexOptions.Singleline
修饰符。但是,在JS中,不支持修饰符,但您可以使用[\s\S]
解决方法模式匹配任何char。
因此,为了使两种正则表达式兼容而需要进行的最小更改是将([^]|:)
更改为[\s\S]
,因为不需要使用:
作为替代(因为[\s\S]
已匹配冒号)。
另外,请勿使用[A-z]
作为匹配ASCII字母的快捷方式。使用[a-zA-Z]
或[a-z]
并传递不区分大小写的修饰符。
因此,您可以考虑将表达式编写为
{([A-Za-z]*)([\s\S]((\\:)|[^:])*?)([\s\S]((\\:)|[^:])*?)}
查看.NET regex test和JS regex test。
当然,这里可能还有其他一些增强功能:删除冗余组,添加对任何转义序列的支持(不仅仅是转义冒号)等,但它不在问题范围内。