ACCPV4.0网络爬虫系列讲座(一)C#正则表达式应用ACCPV4.02前言互联网高速发展的今天,信息越来越多样化,我们更加依赖于网络给我们带来的便利,从Web页面上检索数据获取信息是网民最基本的需求。我们面向于互联网所带来的海量数据的同时,发现人工检索收录有用的数据时已经力不从心,甚至根本不可行,这时候我发现需要一种方法解决此问题–网络爬虫(又称:网络蜘蛛,搜索引擎重要的组成部分)。网络爬虫获取到的数据是原始数据,其中可能有我们所需的信息可能也没有,或则同时也可能含有大量我们不关心的信息,因此我们需要对有用数据进行处理,最常规的方法是利用某种语言的条件判断语句、字符串处理函数等进行处理,但通常这样使解决方案变的十分复杂,编写十分不变,而且BUG很多。使用正则表达式解决上述问题是最佳的、也是最简单的方法。ACCPV4.03本章目标理解为什么要使用正则表达式理解正则表达式的语法理解正则表达式的普通字符、特殊字符理解并编写正则表达式ACCPV4.04问题我们在Windows上搜索EXE扩展名的文件可以在搜索对话框中输入“*.EXE”,然后搜索。若要搜索字母A开头的EXE文件,我们可以输如“A*.EXE”。问题:我们可以实现以字符“A”开始并且只能出现一次并且扩展名是“EXE”这样的文件搜索吗?我们可以指定只允许出现指定的字符(如:只允许出现字母:A、B、C和数字:5、8、9)或指定出现字符的重复次数的搜索吗?ACCPV4.05解决答案是否定的!怎么办?这就是我们使用正则要解决的问题!什么是正则表达式?正则表达式是如何解决这类问题的?ACCPV4.06正则表达式简介在典型的搜索和替换操作中,必须提供要查找的确切文字。这种技术对于静态文本中的简单搜索和替换任务可能足够了,但是由于它缺乏灵活性,因此在搜索动态文本时就有困难了,甚至是不可能的。使用正则表达式,就可以:1.测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证。2.替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字。3.根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。ACCPV4.07正则表达式应用实例简介使用正则最典型的案例之一,就是从Web上获取并检索有用的数据,并保存在数据库,供以后使用。例如:天气预报查询商机信息抓取域名信息查询……ACCPV4.08正则表达式应用实例简介实例:获取天气预报信息ACCPV4.09正则表达式应用实例简介实例:从B2B网站商机信息抓取ACCPV4.010正则表达式应用实例简介实例:域名信息查询ACCPV4.011正则表达式应用实例简介扩展实例:网站图片验证码识别ACCPV4.012正则表达式简介正则表达式中的普通字符未显式指定为元字符的打印和非打印字符组成大写和小写字母字符所有数字所有标点符号以及一些符号所有中文字符正则表达式中的特殊字符(称为元字符)正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配ACCPV4.013最简单的正则表达式是一个单独的普通字符,可以匹配所搜索字符串中的该字符本身。例如,单字符模式‘A’可以匹配所搜索字符串中任何位置出现的字母‘A’。这里有一些单字符正则表达式模式的示例:a7M“可以将多个单字符组合在一起得到一个较大的表达式。就是通过组合单字符表达式'a'、'7'以及'M'所创建出来的一个表达式:a7M正则表达式中的普通字符ACCPV4.014有不少很有用的非打印字符,偶尔必须使用。下表显示了用来表示这些非打印字符的转义序列:\cx匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的'c'字符\f匹配一个换页符。等价于\x0c和\cL\n匹配一个换行符。等价于\x0a和\cJ\r匹配一个回车符。等价于\x0d和\cM\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]\S匹配任何非空白字符。等价于[^\f\n\r\t\v]\t匹配一个制表符。等价于\x09和\cI\v匹配一个垂直制表符。等价于\x0b和\cK\w匹配包括下划线的任何单词字符。等价于‘[A-Za-z0-9_]’。\W匹配任何非单词字符。等价于'[^A-Za-z0-9_]'。正则表达式中的非打印字符ACCPV4.015^匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配^字符本身,请使用\^$匹配输入字符串的结尾位置。如果设置了正则对象的Multiline属性,则$也匹配'\n'或'\r'。要匹配$字符本身,请使用\$()标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用\(和\)*匹配前面的子表达式零次或多次。要匹配*字符,请使用\*+匹配前面的子表达式一次或多次。要匹配+字符,请使用\+正则表达式中的特殊字符ACCPV4.016.匹配除换行符\n之外的任何单字符。要匹配.请使用\.[]标记一个中括号表达式。要匹配[],请使用\[\]?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配?字符,请使用\?。\将下一个字符标记为或特殊字符、或原义字符、或后向引用、或八进制转义符。例如,'n'匹配字符'n'。'\n'匹配换行符。序列'\\'匹配\,而'\('则匹配(。{}标记限定符表达式。要匹配{},请使用\{\}|指明两项之间的一个选择。要匹配|,请使用\|正则表达式中的特殊字符ACCPV4.017*匹配前面的子表达式零次或多次。例如,go*能匹配“g以及“goo“+匹配前面的子表达式一次或多次。例如,‘go+'能匹配“go以及“goo,但不能匹配“g?匹配前面的子表达式零次或一次。例如,“goog(le)?可以匹配“goog或“google中的goog{n}n是一个非负整数。匹配确定的n次。例如,'o{2}'不能匹配“gogle中的'o',但是能匹配“google中的两个o{n,}n是一个非负整数。至少匹配n次。例如,‘o{2,}’不能匹配“gogle”中的‘o’,但能匹配“gooooogle”中的所有o{n,m}m和n均为非负整数,其中n=m。最少匹配n次且最多匹配m次。“o{1,3}”将匹配“gooooogle”中的前三个o请注意在逗号和两个数之间不能有空格。正则表达式中的限定符ACCPV4.018[]中括号用于匹配(或不匹配)字符集合、字符范围、数字范围:匹配字符集合:[abcxyz]匹配字符范围:[a-z]、[a-h]匹配数字范围:[0-9]、[4-7]匹配字符和数字范围:[a-z0-9]不匹配字符集合:[^abcxyz]不匹配字符范围:[^a-z]、[^a-h]不匹配数字范围:[^0-9]、[^4-7]不匹配字符和数字范围:[^a-z0-9]正则表达式中的中括号ACCPV4.019()用来建立子表达式,并可指定是否获取这一匹配(pattern)匹配pattern并获取这一匹配。所获取的匹配可以从正则对像的Match.Groups集合得到。(?:pattern)匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用(?=pattern)正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用(?!pattern)负向预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用正则表达式中的子表达式ACCPV4.020^匹配输入字符串的开始位置。如果构造正则对象时指定了RegexOptions.Multiline枚举数,^也匹配'\n'或'\r'之后的位置。$匹配输入字符串的结束位置。如果构造正则对象时指定了RegexOptions.Multiline枚举数,$也匹配'\n'或'\r'之前的位置。\b匹配一个单词边界,也就是指单词和空格间的位置。\B匹配非单词边界。正则表达式中的定位符ACCPV4.021\转义符(),(?:),(?=),[]圆括号和方括号*,+,?,{n},{n,},{n,m}限定符^,$,\anymetacharacter位置和顺序|“或”操作正则表达式中的优先权顺序ACCPV4.022(pattern)匹配pattern并获取这一匹配。所获取的匹配可以从产生的MatchCollection集合得到。要匹配圆括号字符,请使用'\('或'\)'。(?:pattern)匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符(|)来组合一个模式的各个部分是很有用。例如,'industr(?:y|ies)就是一个比'industry|industries'更简略的表达式。(?=pattern)正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows正则表达式语法红色方块标记表示特别常用ACCPV4.023(?!pattern)负向预查,在任何不匹配的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows(?!95|98|NT|2000)'能匹配Windows3.1中的Windows,但不能匹配Windows2000中的Windows。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始x|y匹配x或y。例如,'z|food'能匹配z或food。'(z|f)ood'则匹配zood或food。[xyz]字符集合。匹配所包含的任意一个字符。例如,'[abc]'可以匹配plain中的'a'。[^xyz]负值字符集合。匹配未包含的任意字符。例如,'[^abc]'可以匹配plain中的'p'。正则表达式语法ACCPV4.024[a-z]字符范围。匹配指定范围内的任意字符。例如,'[a-z]'可以匹配'a'到'z'范围内的任意小写字母字符。[^a-z]负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]'可以匹配任何不在'a'到'z'范围内的任意字符。\b匹配一个单词边界,也就是指单词和空格间的位置。例如,'er\b'可以匹配never中的'er',但不能匹配verb中的'er'。\B匹配非单词边界。'er\B'能匹配verb中的'er',但不能匹配never中的'er'。\cx匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的'c'字符。正则表达式语法ACCPV4.025\d匹配一个数字字符。等价于[0-9]。\D匹配一个非数字字符。等价于[^0-9]。\f匹配一个换页符。等价于\x0c和\cL。\n匹配一个换行符。等价于\x0a和\cJ。\r匹配一个回车符。等价于\x0d和\cM。\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。\S匹配任何非空白字符。等价于[^\f\n\r\t\v]。\t匹配一个制表符。等价于\x09和\cI。正则表达式语法ACCPV4.026\v匹配一个垂直制表符。等价于\x0b和\cK。\w匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'\W匹配任何非单词字符。等价于'[^A-Za-z0-9_]'。\xn匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41'匹配A。'\x04