专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » 正则表达式高级:正则表达式高级学习窍门技巧 »正文

正则表达式高级:正则表达式高级学习窍门技巧

来源: 发布时间:星期日, 2009年9月6日 浏览:2次 评论:0
什么是RE?
  想必各位大大在做文件查找时侯都有使用过万用”*”比如说想查找在Windows目录下所有Word文件时你可能就会用”*.doc”这样方式来做查找”*”所代表是任意RE所做就是类似这样功能但其功能更为强大
  写常需要比对串是否符合特定样式RE最主要功能就是来描述这特定样式因此可以将RE视为特定样式描述式举个例子来说”\w+”所代表就是任何字母和数字所组成非空串(non-null )在.NET framework中提供了非常强大类别库藉此可以很轻易使用RE来做文字查找和取代、对复杂标头译码及验证文字等工作
接下来就让我们来体验些例子吧
  些简单例子
  假设要查找文章中Elvis后接有alive使用RE可能会经过下列过程括号是所下RE意思:
  1. elvis (查找elvis)
  上述代表所要查找顺序为elvis在.NET中可以设定乎略大小写所以”Elvis”、”ELVIS”或者是”eLvIs”都是符合1所下RE这只管出现顺序为elvis所以pelvis也是符合1所下RE可以用2RE来改进
  2. \belvis\b (将elvis视为整体字查找如elvis、Elvis乎略大小写时)
“\b”在RE中有特别意思在上述例子中所指就是字边界所以\belvis\b用\b把elvis前后边界界定出来也就是要elvis这个字
  假设要将同行里elvis后接有alive串找出来此时就会用到另外 2个特别意义”.”及”*””.”所代表就是除了换行任意而”*”所代表是重复*的前项目直到找到符合RE所以”.*”所指就是除了换行任意数目所以查找同行里elvis后接有alive串找出来则可下如3的RE
  3. \belvis\b.*\balive\b (查找elvis后面接有alive如elvis is alive)
  用简单的特别就可以组成功能强大RE但也发现当使用越来越多特别RE就会越来越难看得懂了

再看看另外例子
  组成有效电话号码
  假使要从网页上收集顾客格式为xxx-xxxx7位数字电话号码其中x是数字RE可能会这样写
  4. \b\d\d\d-\d\d\d\d (查找 7位数字的电话号码如123-1234)
  每个\d代表个数字”-”则是为避免太多重复\dRE可以改写成如5方式
  5. \b\d{3}-\d{4} (查找 7位数字电话号码较好思路方法如123-1234)
  在\d后{3}代表重复前个项目 3次也就是相等于\d\d\d
  RE学习及测试工具 Expresso
  RE不易阅读及使用者容易会下错RE特性Jim大大开发了个工具软件SoftwareExpresso用来帮助使用者学习及测试RE除了上面所述网址的外也可以上Ultrapico网站WebSite安装完expresso后在expression%20%20library中jim大大把文章例子都建立在其中可以边看文章边测试也可以试着修改范例所下re马上可以看到结果小弟觉得非常好用各位大大可以试试/"安装完Expresso后在Expression Library中Jim大大把文章例子都建立在其中可以边看文章边测试也可以试着修改范例所下RE马上可以看到结果小弟觉得非常好用各位大大可以试试
  .NET中RE基础概念
  特殊
  有些有特别意义比如的前所看到”\b”、”.”、”*”、”\d”等”\s”所代表是任意空格符比如说spaces、tabs、lines等.”\w”代表是任意字母或数字
  再看些例子吧
  6. \ba\w*\b (查找a开头如able)
  这RE描述要查找个字开始边界(\b)再来是字母”a”再加任意数目字母数字(\w*)再接结束这个字结束边界(\b)
  7. \d+ (查找数字串)
  “+”和”*”非常相似除了+至少要重复前面项目也就是说至少有个数字
  8. \b\w{6}\b (查找 6个字母数字如ab123c)
  下表为RE常用特殊
  . 除了换行任意
  \w 任意字母数字
  \s 任意空格符
  \d 任意数字
  \b 界定字边界
  ^ 文章开头如”^The'' 用以表示出现于文章开头串为”The”
  $ 文章结尾如”End$”用以表示出现在文章结尾为”End”
  特殊”^”及”$”是用来查找某些字必需是文章开头或结尾这在验证输入是否符合某样式时特别用有比如说要验证 7位数字电话号码可能会输入如下9RE
  9. ^\d{3}-\d{4}$ (验证 7位数字的电话号码)
  这和第5个RE相同但其前后都无其它也就是整串串只有这 7个数字电话号码在.NET中如果设定Multiline这个选项则”^”和”$”会每行进行比较只要某行开头结尾符合RE即可而不是整个文章串做次比较
  转意(Escaped characters)
  有时可能会需要”^”、”$”单纯字面意义(literal meaning)而不要将它们当成特殊此时”\”就是用来移除特殊特别意义因此”\^”、”\.”、”\\”所代表就是”^”、”.”、”\”字面意义
  重复前述项目
  在前面看过”{3}”及”*”可以用来重复前述的后我们会看到如何用同样语法重复整个次描述(subexpressions)下表是使用重复前述项目些方式
  * 重复任意次数
  + 重复至少
  ? 重复零次或
  {n} 重复n次
  {n,m} 重复至少n次但不超过m次
  {n,} 重复至少n次
  再来试些例子吧
  10. \b\w{5,6}\b (查找 5个或 6个字母数字如as25d、d58sdf等)
  11. \b\d{3}\s\d{3}-\d{4} (查找十个数字电话号码如800 123-1234)
  12. \d{3}-\d{2}-\d{4} (查找社会保险号码如 123-45-6789)
  13. ^\w* (每行或整篇文章个字)
  在Espresso可试试有Multiline和没Multiline区别
  匹配某范围
  有时需要查找某些特定时如何辨?这时中括号””就派上了用场因此[aeiou]所要查找是”a”、”e”、”i”、”o”、”u”这些元音[.?!]所要查找是”.”、”?”、”!”这些符号在中括号中特殊特别意义都会被移除也就是解译成单纯字面意义也可以指定某些范围如”[a-z0-9]”所指就是任意小写字母或任意数字
  接下来再看个比较初复杂查找电话号码RE例子
  14. \(?\d{3}[( ] \s?\d{3}[- ]\d{4} (查找十位数字的电话号码如(080) 333-1234 )
  这样RE可查找出较多种格式电话号码如(080) 123-4567、511 254 6654等”\(?”代表个或零个左小括号”(“而”[( ]”代表查找个右小括号”)”或空格符”\s?”指个或零个空格符组但这样RE会将类似”800) 45-3321”这样电话找出来也就是括号没有对称平衡问题的后会学到择(alternatives)来决解这样问题
  不包含在某特定组里(Negation)
  有时需要查找在包含在某特定组里下表介绍说明如何做类似这样描述
  \W 不是字母数字任意
  \S 不是空格符任意
  \D 不是数字任意
  \B 不在字边界位置
  [^x] 不是x任意
  [^aeiou] 不是a、e、i、o、u任意
  15. \S+ (不包含空格符串)
  择(Alternatives)
  有时会需要查找几个特定选择此时”|”这个特殊就派上用场了举例来说要查找 5个数字及 9个数字(有”-”号)邮政编码
  16. \b\d{5}-\d{4}\b|\b\d{5}\b (查找 5个数字及 9个数字(有”-”号)邮政编码)
  在使用Alternatives时需要注意是前后次序RE在Alternatives中会优先选择符合最左边项目16中如果把查找 5个数字项目放在前面则这RE只会找到 5个数字邮政编码了解了择可将14做更好修正
  17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4} (十个数字电话号码)
  群组(Grouping)
  括号可以用来介定个次描述经由次描述介定可以针对次描述做重复或及他处理
  18. (\d{1,3}\.){3}\d{1,3} (寻找网络地址简单RE)
  此RE意思第个部分(\d{1,3}\.){3}所指数字最小位最多 3位并且后面接有”.”符号此类型共有 3个的后再接到 3位数字也就是如192.72.28.1这样数字
  但这样会有个缺点网络地址数字最多只到255但上述RE只要是到 3位数字都是符合所以这需要让比较数字小于256才行但只单独使用RE并无法做这样比较在19中使用择来将地址限制在所需要范围内也就是0到255
  19. ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) (寻找网络地址)
  有没有发觉RE越来越像外星人说话了?就以简单寻找网络地址直接看RE都满难理解
  Expresso Analyzer View
  Expresso提供了个功能它可以将所下RE变成树状介绍说明组组分开介绍说明提供了个好除错环境其它功能如部分符合(Partial Match只查找反白RE部分)及除外符合(Exclude Match只不查找反白RE部分)就留给各位大大试试啰
  当次描述用括号群组起来时符合次描述文字可用在的后处理或RE本身在预设情型下所符合群组是由数字命名由1开始由顺序是由左至右这自动群组命名可在Expresso中skeleton view或result view中看到
  Backreference是用来查找群组中抓取符合文字所相同文字举例来说”\1”所指符合群组1所抓取文字
  20. \b(\w+)\b\s*\1\b (寻找重复字此处说重复是指同样中间有空白隔开如dog dog这样字)
(\w+)会抓取至少字母或数字并将它命名为群组1的后是查找任意空格符再接和群组1相同文字
  如果不喜欢群组自动命名1也可以自行命名以上述例子为例(\w+)改写为(?<Word>\w+)这就是将所抓取群组命名为WordBackreference就要改写成为\k<Word>
21. \b(?<Word>\w+)\b\s*\k<Word>\b (使用自行命名群组抓取重复字)
  使用括号还有许多特别语法元素比较通用列表如下:
  抓取(Captures)
  (exp) 符合exp并抓取它进自动命名群组
  (?<name>exp) 符合exp并抓取它进命名群组name
  (?:exp) 符合exp不抓取它
  Lookarounds
  (?=exp) 符合字尾为exp文字
  (?<=exp) 符合前缀为exp文字
  (?!exp) 符合后面没接exp字尾文字
  (?<!exp) 符合前面没接exp前缀文字
  批注Comment
  (?#comment) 批注
  Positive Lookaround
  接下来要谈是lookahead及lookbehind assertions它们所查找是目前符合的前或的后文字并不包含目前符合本身这些就如同”^”及”\b”特殊本身并不会对应任何文字(用来界定位置)也因此称做是zero-width assertions看些例子也许会清楚些
  (?=exp)是个”zero-width positive lookahead assertion”它指就是符合字尾为exp文字但不包含exp本身
  22. \b\w+(?=ing\b) (字尾为ing比如说filling所符合就是fill)
(?<=exp)是个”zero-width positive lookbehind assertion”它指就是符合前缀为exp文字但不包含exp本身
  23. (?<=\bre)\w+\b (前缀为re比如说repeated所符合就是peated)
  24. (?<=\d)\d{3}\b (在字尾 3位数字且的前接位数字)
  25. (?<=\s)\w+(?=\s) (由空格符分隔开字母数字串)
  Negative Lookaround
  的前有提到如何查找个非特定或非在特定群组但如果只是要验证某不存在而不要对应这些进来呢?举个例子来说假设要查找个字字母里有q但接下来字母不是u可以用下列RE来做
  26. \b\w*q[^u]\w*\b (个字其字母里有q但接下来字母不是u)
  这样RE会有个问题[^u]要对应所以若q是字最后个字母[^u]这样下法就会将空格符对应下去结果就有可能会符合 2个字比如说”Iraq haha”这样文字使用Negative Lookaround就能解决这样问题
  27. \b\w*q(?!u)\w*\b (个字其字母里有q但接下来字母不是u)
  这是”zero-width negative lookahead assertion”
  28. \d{3}(?!\d) ( 3个位数字其后不接个位数字)
  同样可以使用(?<!exp)”zero-width negative lookbehind assertion”来符合前面没接exp前缀
  29. (?<![a-z ])\w{7} ( 7个字母数字其前面没接字母或空格)
30. (?<=<(\w+)>.*(?=<\/\1> (HTML卷标间文字)
  这使用lookahead及lookbehind assertion来取出HTML间文字不包括HTML卷标
  请批注(Comments Please)
  括号还有个特殊用途就是用来包住批注语法为”(?#comment)”若设定”Ignore Pattern Whitespace”选项则RE中空格符当RE使用时会乎略此选项设定时”#”的后文字会乎略
  31. HTML卷标间文字加上批注
  (?<=  #查找前缀但不包含它
  <(\w+)> #HTML标签
  ) #结束查找前缀
  .* #符合任何文字
  (?= #查找字尾但不包含它
  <\/\1> #符合所抓取群组1的也就是前面小括号HTML标签
  ) #结束查找字尾
  寻找最多字及最少字(Greedy and Lazy)
  当RE下要查找个范围重复时(如”.*”)它通常会寻找最多符合字也就是Greedy matching举例来说
  32. a.*b (开始为a结束为b最多符合字)
  若有串是”aabab”使用上述RE所得到符合串就是”aabab”这是寻找最多有时希望是符合最少字也就是lazy matching只要将重复前述项目表加上问号(?)就可以把它们全部变成lazy matching因此”*?”代表就是重复任意次数但是使用最少重复次数来符合举个例子来说:
  33. a.*?b (开始为a结束为b最少符合字)
  若有串是”aabab”使用上述RE第个所得到符合串就是”aab”再来是”ab”这是寻找最少
  *? 重复任意次数最少重复次数为原则
  +? 重复至少最少重复次数为原则
  ?? 重复零次或最少重复次数为原则
  {n,m}? 重复至少n次但不超过m次最少重复次数为原则
  {n,}? 重复至少n次最少重复次数为原则
还有什么没提到呢?
  到目前为止已经提到了许多建立RE元素当然还有许多元素没有提到下表整理了些没提到元素在最左边字段数字是介绍说明在Expresso中例子
  # 语法 介绍说明
  \a Bell
  \b 通常是指字边界组里所代表就是backspace
  \t Tab
  34 \r Carriage
  \v Vertical Tab
  \f From feed
  35 \n New line
  \e Escape
  36 \nnn ASCII 8位码为nnn
  37 \xnn 十 6位码为nn
  38 \unnnn Unicode为nnnn
  39 \cN Control N举例来说Ctrl-M是\cM
  40 \A 开始(和^相似但不需籍由multiline选项)
  41 \Z 结尾
  \z 结尾
  42 \G 目前查找开始
  43 \p{name} Unicode 组名称为name比如说\p{Lower_Letter} 所指就是小写字
  (?>exp) Greedy次描述又称的为non-backtracking次描述这只符合次且不采backtracking
  44 (?<x>-<y>exp)
  or (?-<y>exp) 平衡群组虽复杂但好用它让已命名抓取群组可以在堆栈中操作使用(小弟对这个也是不太懂哩)
  45 (?im-nsx:exp) 为次描述exp更改RE选项比如(?-i:Elvis)就是把Elvis大乎略大小写选项关掉
  46 (?im-nsx) 为的后群组更改RE选项
  (?(exp)yes|no) 次描述exp视为zero-width positive lookahead若此时有符合则yes次描述为下个符合标若否则no 次描述为下个符合标
  (?(exp)yes) 和上述相同但无no次描述
  (?(name)yes|no) 若name群组为有效群组名称则yes次描述为下个符合标若否则no 次描述为下个符合标
  47 (?(name)yes) 和上述相同但无no次描述
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: