正则表达式的可变长度lookbehind-assertion替代方案 [英] Variable-length lookbehind-assertion alternatives for regular expressions

查看:506
本文介绍了正则表达式的可变长度lookbehind-assertion替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python / PHP / JavaScript中是否有正则表达式的实现支持可变长度的lookbehind-assertion?

  / (?<!foo。*)bar / 

如何编写具有相同的含义,但不使用lookbehind-assertion?



这种类型的断言是否有可能在某一天实现?



我认为事情要好得多。



更新:



(1)有正则表达式实现支持变量-bere lookbehind-assertion已经。



Python模块正则表达式(不是标准的 re ,但额外的 regex 模块)支持这样的断言(还有许多其他很酷的功能) )。

 >>> import regex 
>>> m = regex.search('(?<!foo。*)bar','f00bar')
>>> print m.group()
bar
>>> m = regex.search('(?<!foo。*)bar','foobar')
>>>打印m

对我来说,有一些事情是非常令我惊讶的Perl不能做的表达式和Python可以做的表达式。可能还有Perl的增强正则表达式实现吗?



(谢谢和MRAB +1)。



(2)现代正则表达式中有一个很酷的功能 \K



此符号表示当你进行替换时(从我的角度来看,最有趣的断言用例是替换),在 \K 之前找到的所有字符都不能是改变。

  s / unchanged-part\Kchanged-part / new-part / x 

这几乎就像一个后视断言,但当然不是那么灵活。



更多关于 \ K




  • Perl正则表达式\K技巧

  • PCRE正则表达式聚焦:\ K



  • 据我所知,你不能在同一个正则表达式中使用\K两次。而且你不能说你想要杀死你找到的角色。这总是直到行的开头。



    (谢谢和ikegami +1)。



    我的其他问题:




    • 是否有可能说出 \ K 效果?

    • Perl / Ruby / JavaScript / PHP的增强型正则表达式实现怎么样? Python的 regex 之类的东西。


    解决方案

    大多数情况下,您可以使用<$ c $来避免可变长度的回顾c> \K

      s /(?< = foo。*)bar /も/秒; 

     < 。code> S / FOO * \Kbar / MOO /秒; 

    负面观察有点棘手。

      S /(小于?!FOO *)酒吧/ MOO /秒; 

      S / ^)* \Kbar / MOO /秒(:(?FOO?)。 

    因为(?:(?!STRING)。)* STRING [^ CHAR] * CHAR






    如果您只是匹配,您甚至可能不需要 \K

      /foo.*bar/s 

    /^(?:(??foo).)*bar/s


    Is there an implementation of regular expressions in Python/PHP/JavaScript that supports variable-length lookbehind-assertion?

    /(?<!foo.*)bar/
    

    How can I write a regular expression that has the same meaning, but uses no lookbehind-assertion?

    Is there a chance that this type of assertion will be implemented some day?

    Things are much better that I thought.

    Update:

    (1) There are regular expressions implementation that support variable-length lookbehind-assertion already.

    Python module regex (not standard re, but additional regex module) supports such assertions (and has many other cool features).

    >>> import regex
    >>> m = regex.search('(?<!foo.*)bar', 'f00bar')
    >>> print m.group()
    bar
    >>> m = regex.search('(?<!foo.*)bar', 'foobar')
    >>> print m
    None
    

    It was a really big surprise for me that there is something in regular expressions that Perl can't do and Python can. Probably, there is "enhanced regular expression" implementation for Perl also?

    (Thanks and +1 to MRAB).

    (2) There is a cool feature \K in modern regular expressions.

    This symbols means that when you make a substitution (and from my point of view the most interesting use case of assertions is the substitution), all characters that were found before \K must not be changed.

    s/unchanged-part\Kchanged-part/new-part/x
    

    That is almost like a look-behind assertion, but not so flexible of course.

    More about \K:

    As far as I understand, you can't use \K twice in the same regular expression. And you can't say till which point you want to "kill" the characters that you've found. That is always till the beginning of the line.

    (Thanks and +1 to ikegami).

    My additional questions:

    • Is it possible to say what point must be the final point of \K effect?
    • What about enhanced regular expressions implementations for Perl/Ruby/JavaScript/PHP? Something like regex for Python.

    解决方案

    Most of the time, you can avoid variable length lookbehinds by using \K.

    s/(?<=foo.*)bar/moo/s;
    

    would be

    s/foo.*\Kbar/moo/s;
    

    Negative lookbehinds are a little trickier.

    s/(?<!foo.*)bar/moo/s;
    

    would be

    s/^(?:(?!foo).)*\Kbar/moo/s;
    

    because (?:(?!STRING).)* is to STRING as [^CHAR]* is to CHAR.


    If you're just matching, you might not even need the \K.

    /foo.*bar/s
    
    /^(?:(?!foo).)*bar/s
    

    这篇关于正则表达式的可变长度lookbehind-assertion替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆