首次在C#中使用Regex遇匹配问题,求正确正则表达式
解决C#正则匹配多个
[http: ...]块的问题 嘿,我完全懂你从SQL Server正则转C#时的挫败感——这俩的匹配行为真的有不少差异,尤其是贪婪匹配这块坑了很多人!
为什么你的当前代码只返回一个匹配?
你的正则模式.*[[]http:.*[]]里的.*是贪婪匹配的,它的特性是尽可能多地抓取字符:
- 开头的
.*会从字符串起始位置一直“吃”到最后一个[http:的前一个字符(而不是第一个) - 后面的
.*[]]接着匹配到最后一个],所以最终整个匹配结果是从字符串开头到最后一个]的一大段,自然只返回一个匹配。
如果给模式末尾加.*,贪婪的.*会直接吞掉整个字符串,所以匹配结果就是完整的输入文本。
正确的正则模式
要匹配每个独立的[http: ...]块,我们需要用否定字符组来限制匹配范围,这种方式直观又高效:
\[http: [^\]]+\]
逐个解释各部分:
\[:转义左方括号([在正则里是字符组的特殊开头,必须转义才能匹配字面量)http::匹配固定的字面量文本[^\]]+:否定字符组,匹配任意不是右方括号]的字符,+表示至少匹配一次——这样匹配会在遇到第一个]时立即停止,不会贪婪地往后延伸\]:转义右方括号,匹配字面量的]
修改后的完整代码
把你的代码替换成这个,就能得到预期的三个匹配了:
static void Main(string[] args) { string FullString = "[http: Something] One Two Three[http: AnotherOne] Four[http: BlahBlah] sdksaod,cne 9ofew {}@:P{"; Regex regex = new Regex(@"\[http: [^\]]+\]"); // 用@逐字字符串避免转义混乱 foreach (Match match in regex.Matches(FullString)) { Console.WriteLine(match.Value); } Console.ReadKey(); }
这里用了C#的逐字字符串(@开头),这样正则里的反斜杠不需要再额外转义,代码可读性更强。
额外小提示
如果你的字符串里可能存在跨行的[http: ...]块(比如[http: Line\nBreak]),可以给正则加上RegexOptions.Singleline选项,不过你的例子场景里暂时用不上这个。
内容的提问来源于stack exchange,提问作者Michał Turczyn
相关产品推荐
相关产品推荐

