我写文章的一个最基本的想法就是只写可以解决问题的部分,这样能很快的解决一个问题,而不探讨这项技术中的复杂的技术细节,这样有好处也有坏处。好处是我写的文章都简单明了,坏处是我写的东西不一定能解决你的问题。同样,写的文章也往往不能解决我自己将来遇到的问题。
自己之前写过:C#正则表达式的应用,但现在我又遇到了新的问题。
问题描述如下:我有一系列点号,如C120、C121、C122。首先我想判断这个点号是不是(字母开头,后面加数字)的形式。如果是,我想把字母提取出来。
第一个要求用前面的文章中的东西很容易就达到了,代码如下:
string pattern = "/b[A-Za-z]+[0-9]+/b"; MatchmatResult = Regex.Match(selectedLines[0].Name, pattern); if (!matResult.Success) //不成功说明不符合要求,do something else //成功,do something
但是现在的匹配结果是像C120这样的整个的符串,并达不到自己想提取前面C的要求。
要解决这个问题,就要用到 零宽断言 。零宽断言的意思是:匹配宽度为零,满足一定的条件/断言。用这个例子来说就是要求字母后面是数字,但不匹配(匹配宽度为零)后面的数字。
最常用的断言有两种,分别是 先行断言 和 后行断言。
先行断言的意思是匹配部分在前面,然后后面加断言。表达形式为(?=exp)。这个正好适用于现在这个情况。先给出表达式/b[a-zA-Z]+(?=[0-9]+/b)。在括号之前的就是C#正则表达式的应用中说明的内容,这里不再多说。括号里面就是 先行断言 。表示前面先是字母,后面以数字结尾,但不匹配数字。如果对C120使用这个表达式则匹配C
后行断言意思恰好和先行断言相反。类似于上面那个问题,如果我们想匹配C120中的120,则表达式为(?<=/b[a-zA-Z]+)[0-9]+/b。技术细节不再多说。
断言其实还有其他的种类,这里没有用到,暂时不多说。