drpph80800 2014-02-02 10:35
浏览 47
已采纳

为什么这个正则表达式在PHP中并不贪心

This regex should match lists just like in Markdown:

/((?:(?:(?:^[\+\*\-] )(?:[^
]+))(?:|
?))+)/m

It works in Javascript (with g flag added) but I have problems porting it to PHP. It does not behave greedy. Here's my example code:

$string = preg_replace_callback('`((?:(?:(?:^\* )(?:[^
]+))(?:|
?))+)`m', array(&$this, 'bullet_list'), $string);

function bullet_list($matches) { var_dump($matches) }

When I feed to it a list of three lines it displays this:

array(2) { [0]=> string(6) "* one " [1]=> string(6) "* one " } array(2) { [0]=> string(6) "* two " [1]=> string(6) "* two " } array(2) { [0]=> string(8) "* three " [1]=> string(8) "* three " } 

Apparently var_dump is being called three times instead of just once as I expect from it since the regex is greedy and must match as many lines as possible. I have tested it on regex101.com. How do I make it work properly?

  • 写回答

3条回答 默认 最新

  • 我在西湖1 2014-02-02 10:41
    关注

    This regex won't work correctly if you have newlines in your input text.

    The part (?:| ?) matches either an or an , but not both. (regex101 treats newlines as only, so it works there).

    Does the following work?

    /(?:(?:(?:^[+*-] )(?:[^
    ]+))[
    ]*)+/m
    

    (or, after removal of all the unnecessary non-capturing groups - thanks @M42!)

    /(?:^[+*-] [^
    ]+[
    ]*)+/m
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?