正则表达式是只纸老虎(一)Hello, Regex!

1 篇文章 0 订阅
1 篇文章 0 订阅

写在前面的话:

我是懒人,于是我相信自己是懒人,于是我越来越懒……

虽然正则表达式是个非常历史悠久而且非常通用的东西,但还是有不少童鞋表示这玩艺其实很难懂。

网上资料已然一大堆,但想想为了让自己不再那么懒,那就从正则表达式起,尽力发表一些自己的见解吧。

本系列就命名为《正则表达式是只纸老虎》,由简入难,尽可能介绍到.net 正则表达式的所有语法及用例和一些开发过程中常用的使用场景。



不怎么华丽的分割线


第一关,用来确定一个字符串是否在另一个字符串中出现过。

效果等同于 input.Contains(pattern) 

var pattern = "Hello, Regex!";
var sampleRegex = new Regex(pattern);
var input = "This is a sample input: Hello, Regex!";
var isMatch = sampleRegex.IsMatch(input);
Console.WriteLine("isMatch: {0}", isMatch);

第二关,增加大小写选项。也就是说,我们想要匹配的时候,忽略大小写,要怎么办?

效果等同于 input.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) != -1

只需要改造一句,增加一个选项就搞定。

var sampleRegex = new Regex(pattern, RegexOptions.IgnoreCase);

第三关,判断字符串是否以指定字符串开头和结尾。

效果等同于 input.StartsWith(pattern) 和 input.EndsWith(pattern)

var pattern = "^Hello, Regex!"; //使用^来匹配字符串开头
以及

var pattern = "Hello, Regex!$"; //使用$来匹配字符串结尾

举一反三:

那么  ^abc 就是匹配 abc 开头的,abc$ 就是匹配以 abc 结尾的。

^abc$ 那就是匹配字符串为abc的,因为开头结尾都限制了,相当于判断字符串是否直接等于 abc


第四关,判断字符串中是否包含阿拉伯数字。

var pattern = "[0-9]";

既然这里出现了中括号,那么,我就说一下中括号是怎么回事情。

[] 存在两种匹配模式,即[exp]和[^exp],注意这里的"^",可不再是匹配字符串开头的意思,这里是取反的意思。

比如 [0-9] 是匹配 0~9 之间的任意数字,而 [^0-9] 是匹配任何非数字,也就是说,只要出现任何一个不是数字的字符,就能匹配。

var pattern = "[0-9]";
var sample1 = "现在是2014年"; //匹配
var sample2 = "这一句没有数字,哪怕中文的1234567890也不行。"; //不匹配
var pattern = "[^0-9]";
var sample1 = "这一句里出现了一个数字,那就是0。"; //匹配
var sample2 = "0123456789"; //不匹配,因为连一个非数字的字符也没有。
var sample2 = "1234567890"; //匹配,因为全角的4,在这里被认为是非数字(其Unicode码位在0-9之外)。

顺便说一下,这里的减号的用法:

[first-last]

其中 first 是范围的开始字符,last 是范围的结束字符。 字符范围是一系列连续的字符,定义的方法是:指定系列中的第一个字符,连字符 (-),然后指定系列中的最后一个字符。 如果两个字符具有相邻的 Unicode 码位,则这两个字符是连续的。

摘自MDSN:http://msdn.microsoft.com/zh-cn/library/20bw873z(v=vs.100).aspx


第五关,小BOSS,综合应用。匹配以英文字母开头,并且以数字结尾的字符串。

var pattern = "^[a-zA-Z].*[0-9]$";
var regex = new Regex(pattern, RegexOptions.Singleline);

//假假造几个样本来测试一下
var samples = new string[]{
    "123456",
    "中文开头111",
    "abcdefg",
    "a1",
    "abc222"
};
            
foreach(var item in samples)
{
    Console.WriteLine("input: {0}, isMatch: {1}", item, regex.IsMatch(item));
}

跟我们设想的一样,只有最后两个样本才匹配。

这里用到了几个新的东西,[a-zA-Z],中括里的,是可以组合的,可以单个字符,也可以是一个区间,任意多个组合。

当然如果不嫌麻烦,也可以把 [a-z] 写成 [abcdefghijk......xyz]把26个字母全写上。

同样的,我们随意写一个 [0-35-7a-fA-E],意思是可以匹配 0,1,2,3,5,6,7,a,b,c,d,e,f,A,B,C,D,E 这些字符中的任何一个。

这里用到了 ".*" ,其中句点字符 (.) 匹配除 \n(换行符 \u000A)之外的任何字符,有以下两个限制:

如果通过 RegexOptions.Singleline 选项修改正则表达式模式,或者通过 s 选项修改包含 . 字符类的模式的部分,则 . 可匹配任何字符。

正字符分组或负字符分组中的句点字符将被视为原义句点字符,而非字符类。

也就是说,如果需要用“.”来匹配换行(\n),必须指定 RegexOptions.Singleline 或者使用 s 选项。同时在中括号中的 [.] 并不是匹配任意字符,而仅是匹配句点“.”本身。

其后的星号“*”,表示匹配任意多次(包含0次)。意思就是,除了开头字母,最后一个数字之外,允许中间出现任何多个任意字符。


OK,五关已过,打完收工。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值