V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
caneman
V2EX  ›  Python

正则,请问如何实现匹配最内层的内容

  •  
  •   caneman · 2020-12-25 14:16:04 +08:00 · 1741 次点击
    这是一个创建于 1211 天前的主题,其中的信息可能已经有所发展或是发生改变。
    123start123
    1111111111
    4567start4567
    ****
    ****
    ****
    789end789
    1234end1234
    

    如何匹配中间的三行 '****',使得最终输出为:

    ***
    ***
    ***
    

    有多个 start 、end 标记(不一定成对出现),start 、end 之前之后的有多个不定长字符

    \n.*start.*\n([\s\S]*?)\n.*end
    

    PS:能解决的方案目前有下面这种,不知道下面这个能不能满足上面的需求(样例之外的),有没有简单点的,或者碰到这种一般怎么解决比较好?

    (?s)\n[^\n]*start[^\n]*\n((.(?!start))*?)\n[^\n]*end
    
    第 1 条附言  ·  2020-12-25 16:16:14 +08:00
    10 条回复    2020-12-25 17:59:58 +08:00
    lululau
        1
    lululau  
       2020-12-25 14:20:35 +08:00
    搜“Python recursive regexp”
    lovecy
        2
    lovecy  
       2020-12-25 14:41:21 +08:00
    你这个我没看懂到底要干什么
    给的正则例子也无法匹配你样例里的中间三行。。。。
    建议重新梳理一下题目
    shyrock
        3
    shyrock  
       2020-12-25 15:34:07 +08:00
    一开始以为是要剥离成对出现的 start 和 end,结果发现不是。那么你要剥离的文本到底是什么特征?就是一行里面有‘start’或者‘end’的都剥离?‘11111111’也剥离?不像啊
    caneman
        4
    caneman  
    OP
       2020-12-25 15:36:29 +08:00
    @lululau
    谢谢~

    @lovecy
    可以的,上面那个第二条才可以
    (?s)\n[^\n]*start[^\n]*\n((.(?!start))*?)\n[^\n]*end
    这个有倆 group,在 group1 里面

    下面这个就只有一个组了
    (?s)\n[^\n]*start[^\n]*\n((?:.(?!start))*?)\n[^\n]*end

    https://regex101.com/r/qWCjxp/1/
    caneman
        5
    caneman  
    OP
       2020-12-25 15:39:41 +08:00
    @shyrock 111 也不要,只要最内层的
    可以理解为最后一个 start 所在的那一行(不包括此行)和第一个 end 所在那一行(不包括此行)中间夹着的东西

    你可以见上面我回复中贴的 regex101 链接
    caneman
        6
    caneman  
    OP
       2020-12-25 15:46:58 +08:00
    @shyrock 可以理解为,分隔符为,由 start 和无序字符组成的行,由 end 和无序字符组成的行,中间夹着的东西(最内层)

    至于我为什么要从\n 开始匹配,是因为,我对这个行的总字数是有要求的,更可能的情况下应该是类似下面这样的

    (?s)\n[^\n]{0,10}start[^\n]{0,10}\n((?:(?<!start).)*?)\n[^\n]{0,10}end
    caneman
        7
    caneman  
    OP
       2020-12-25 16:00:10 +08:00
    上面那个链接,测试文字前面应该再加一行干扰行,用下面这个比较好
    https://regex101.com/r/qWCjxp/2
    wlsnx
        8
    wlsnx  
       2020-12-25 16:41:08 +08:00   ❤️ 1
    (?s).*start[^\n]*\n(.*?)\n[^\n]*end
    稍微短一点
    lovecy
        9
    lovecy  
       2020-12-25 17:53:42 +08:00
    /(?:^.*start.*$\n)((?:(?!start|end)[\s\S])*)(?:^.*end.*$)/gm
    我这个也可以
    lovecy
        10
    lovecy  
       2020-12-25 17:59:58 +08:00
    不同语言的正则引擎实现还是有差异的,你给的链接用的是 PHP ( PCRE )的正则引擎,最好用 PYTHON 的多测试一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1303 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:40 · PVG 01:40 · LAX 10:40 · JFK 13:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.