Board logo

标题: [原创代码] PowerShell 正则表达式平衡组匹配html文档嵌套标签 [打印本页]

作者: WHY    时间: 2018-1-1 04:05     标题: PowerShell 正则表达式平衡组匹配html文档嵌套标签

本帖最后由 WHY 于 2018-1-3 20:16 编辑

今天得空,逛了逛 pstips.net,翻到 http://www.pstips.net/question/7423.html 这一贴,楼主要求用 PowerShell 正则表达式平衡组匹配 html 文档中所有 dl 嵌套标签。

PowerShell 脚本如下:
  1. function GetBalancedConstruct {
  2.     param([ref]$refStr);
  3.     $match = [regex]::Matches($refStr.Value, $reg);      #正则匹配
  4.     $match | ForEach {                                   #遍历匹配集合
  5.         $str = $_.Groups[0].Value;                       #捕获组0的值赋值给变量str
  6.         Write-Host ('第 ' + (++$global:n) + ' 组');      #回显
  7.         Write-Host $str;
  8.         GetBalancedConstruct ([ref]$str.SubString(3))    #递归
  9.     }
  10. }
  11. $str = [IO.File]::ReadAllText('a.html', [Text.Encoding]::Default);  #打开文本、读取文本内容
  12. $reg = '(?i)<dl>((?:(?!</?dl>)[\S\s])*|<dl>(?<Open>)|</dl>(?<-Open>))*(?(Open)(?!))</dl>';  #正则表达式模式
  13. GetBalancedConstruct ([ref]$str)    #调用函数
  14. [Console]::ReadLine()               #暂停
复制代码
如果感兴趣的话可以继续往下看,对脚本中正则表达式模式注释一下:
  1. <dl>(?:(?!</?dl>)[\S\s])*
复制代码
#<dl> 后面跟着非 <dl> 或者非 </dl> 的任意字符,这样的字符重复任意次;
  1. <dl>(?<Open>)
复制代码
#遇到 <dl> 字符,将 Open 捕获组内容压入堆栈,计数加1;
  1. </dl>(?<-Open>)
复制代码
#遇到 </dl> 字符,将 Open 捕获组内容弹出堆栈,计数减1;
  1. (?(Open)(?!))
复制代码
#相当于条件表达式 (?(Open)(?!Expression1)|Expression2), Expression1 和 Expression2 被省略。
#如果 <dl> 和 </dl> 个数不相等,Open 捕获组计数不为0,执行条件分支 (?!),由于 Expression1 被省略,匹配总是失败,回溯进行下一轮匹配;
#如果 <dl> 和 </dl> 个数相等,Open 捕获组计数等于0,执行条件分支 Expression2,由于 Expression2 被省略,也就是不进行任何操作,代表匹配成功。
作者: codegay    时间: 2018-1-1 19:03

顺手贴一下正则的教程吧。有说到平衡组的。
http://deerchao.net/tutorials/regex/regex.htm
作者: WHY    时间: 2018-1-3 20:22

回复 2# codegay


    不错哦!
我也推荐一个吧,想学正则的话可以参考下:
http://www.regular-expressions.info/tutorial.html




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2