查看: 1013|回复: 7
打印 上一主题 下一主题

[教程] 发一个嵌套标签匹配的正则<(?:[^<>]++|(?R))*>

[复制链接]
  • TA的每日心情
    慵懒
    2018-11-26 11:30
  • 签到天数: 130 天

    [LV.7]常住居民III

    2

    主题

    214

    回帖

    2056

    积分

    禁止发言

    积分
    2056
    跳转到指定楼层
    1
    发表于 2018-6-12 02:21:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 cixiplc66 于 2018-6-12 09:50 编辑
    1. <(?:[^<>]++|(?R))*>
    复制代码


    <(?:[^<>]++|(?R))*>

    匹配到尖括号之间内容,允许内部多次嵌套
    核心: (?R)
    平衡组递归匹配
    这个是Autohotkey脚本软件作者Lexikos亲手所出,绝对牛逼高人!

    /*
    正则递归 by_Lexikos
    它可以与“递归调用”结合来删除任意数量的嵌套<...>:

    一个特殊的项目由 (? 后面跟一个大于的数字组成零和一个右括号
    是子模式的递归调用给定的数字,只要它发生在子模式内。
    (如果不是,这是一个“子程序”的调用,这在下一个部分中有描述,)
    特殊项目 (?R) 或 (?0) 是整个递归调用正则表达式。

    这个PCRE模式解决了嵌套的括号问题
    (假设PCRE_EXTENDED选项设置为忽略空白):
    \( ( [^()]++ | (?R) )* \)

    首先它匹配左括号。
    然后它匹配任何数量的可以是非括号序列的子字符串,
    或者a模式本身的递归匹配
    (也就是说,一个正确的parenthe-大小的子字符串)。
    最后有一个右括号。请注意使用的所有格量词,
    以避免回溯成非序列的序列,括号。

    Source: http://www.pcre.org/pcre.txt
    https://autohotkey.com/board/top ... d-text-in-a-string/
    */

    Emeditor 完美支持 (?R) 递归语法

    附上语法解释:
    [DEELX 正则表达式扩展语法:递归表达式 - CSDN博客](https://blog.csdn.net/technofiend/article/details/49905127)

    百度能搜到的唯一一篇讲解的比较清楚的关于(?R)正则递归
    [php匹配嵌套括号内的文本 - xubaoguo - ITeye博客](http://xubaoguo.iteye.com/blog/941406)
    1. (a(b(c)d)(ggg)e))

    2. \(([^()]+|(?R))*\)
    复制代码


    和Lexikos版本主要区别未使用?:不捕获存档组
    Lexikos大使用了2个加号++,不知道是不是针对一些特别的换行符而考虑

    几个变形:
    1. \((?:[^()]+|(?R))*\)

    2. \((?>[^()]+|(?R))*\)
    复制代码

    具体区别还要慢慢体会

    评分

    2

    查看全部评分

    本帖被以下淘专辑推荐:

  • TA的每日心情
    慵懒
    2018-11-26 11:30
  • 签到天数: 130 天

    [LV.7]常住居民III

    2

    主题

    214

    回帖

    2056

    积分

    禁止发言

    积分
    2056
    2
     楼主| 发表于 2018-6-12 02:26:04 | 只看该作者
    本帖最后由 cixiplc66 于 2018-6-12 02:32 编辑

    ?: 后面加上 span class="kwd"
    应该能完美匹配到指定标签了,没测试
    如此简洁匹配到嵌套尖括号也可以换成圆括号的正则表达式,百度了一天我还搜不到

    德国人的英语,Google的翻译也只能凑合看
  • TA的每日心情
    慵懒
    2018-11-26 11:30
  • 签到天数: 130 天

    [LV.7]常住居民III

    2

    主题

    214

    回帖

    2056

    积分

    禁止发言

    积分
    2056
    3
     楼主| 发表于 2018-6-12 03:52:44 | 只看该作者
    再送同样是ahk_L版本老大@lexikos : remove blank lines
    收藏级的去行首行尾空白同时去空行的正则

    正则替换
    1. ^\s+|\s*(\R|$)\s*
    复制代码

    替换为\1

    -----------------------✂-----------------------
    同样效果:

    1. `am)^\s+|\h+$|\R\z
    复制代码
    匹配部分替换为空
    注意 `am)是ahk脚本中语法,表示开启识别多种换行符和匹配多行开头结尾模式

    评分

    1

    查看全部评分

  • TA的每日心情
    慵懒
    2021-11-14 17:58
  • 签到天数: 999 天

    [LV.10]以坛为家III

    3

    主题

    904

    回帖

    15万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    152376

    灌水大神章

    4
    发表于 2018-6-12 07:26:46 | 只看该作者
    请问
    如果是想筛选出尖括号<>以外的内容呢?
    比如A12<DE>F907G
    选择<DE>之外的内容

    谢谢
  • TA的每日心情
    慵懒
    2018-11-26 11:30
  • 签到天数: 130 天

    [LV.7]常住居民III

    2

    主题

    214

    回帖

    2056

    积分

    禁止发言

    积分
    2056
    5
     楼主| 发表于 2018-6-12 09:15:08 | 只看该作者
    本帖最后由 cixiplc66 于 2018-6-12 22:46 编辑

    你这样的需求一般是html源码转txt
    多数是直接匹配 <[^>]*?> 然后替换为空,倒无需考虑嵌套 反而简单了

    备注:
    [^>]也可以用英文句号圆点 . 代替,
    不过小圆点 . 有局限,除非开启 s 模式否则不能匹配到换行符,也就是只能处理一个看得见的行内
    ,默认情况下正则把整个文本看做一行
    小圆点 . 要处理跨行 开启 s 模式
    ^ $ 这2个行首行尾位置标记要处理跨行的内容,要开启 m 模式,其中有3个很少见到的类似效果的 \A \z \Z
    \A 全文开头 \z全文结尾位置
    \Z 无须开启 m 多行模式 就可以匹配行尾和全文结尾
    \R 默认就能代替各种换行符,比\n 灵活出问题少,各种系统搞出来的文本的换行符很复杂,最常见的也有 \r \n \r\n这三种可能

    \K 作用类似于逆向回顾,用于前面是某某某一些字符,比如: a\Kbc 能匹配到bc但是bc前面必须有个a
    类似于 (?=a)bc

    所有全角双字节字符含标点
    1. [[:unicode:]]

    2. 等同于 [^\x00-\xff]
    复制代码



    中日韩双字节全角字符
    1. 含生僻字中文[\x{2E80}-\x{FE4F}]
    2. [\x{3000}-\x{9FFF}] XeCJK 中日韩
    3. // 汉字范围 [\x0391-\xffe5]
    复制代码


    中文标点
    1. [\x{3000}-\x{301e}\x{fe10}-\x{fe19}\x{fe30}-\x{fe44}\x{fe50}-\x{fe6b}\x{ff01}-\x{ffee}]
    2. [中文标点符号unicode码 - CSDN博客](https://blog.csdn.net/miyunhong/article/details/43528897)
    复制代码


    英文标点
    1. [[:punct:]]
    2. \p{Punct}
    复制代码


    1. \p{L} 等于 [a-z]
    2. \p{U} 等于[A-Z]
    复制代码


    匹配某些特定图片img标签,
    1. 允许src有时候不紧跟在 <img 后面
    2. src= 后面可能英文或中文引号,如果可能没有引号还得改为 ['"]?
    1. <img[^>]+src=['"]img/spkr_[^>]+>
    复制代码


    双引号的问题
    多数时候正则中的双引号是个需要特别处理的,比如在一些脚本中,需要连续2个 "" 来代表 一个 "
    只是在一些编辑器中好像又不需要特别处理

    评分

    1

    查看全部评分

  • TA的每日心情
    奋斗
    2019-4-14 02:12
  • 签到天数: 93 天

    [LV.6]常住居民II

    250

    主题

    2966

    回帖

    53万

    积分

    状元

    吃水不忘挖井人

    Rank: 9Rank: 9Rank: 9

    积分
    531111

    灌水大神章笑傲江湖章推广专家QQ 章

    6
    发表于 2019-1-12 00:08:29 | 只看该作者
    ++是为了开启“侵占模式”:走过的路不回头。
  • TA的每日心情

    2022-12-14 17:52
  • 签到天数: 301 天

    [LV.8]以坛为家I

    2

    主题

    536

    回帖

    3602

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3602

    QQ 章

    8
    发表于 2020-7-14 17:25:44 | 只看该作者
    html转txt必备良品,之前自己一个一个标签去匹配真是蠢到家了,收藏了