如何使用preg_match_all从字符串中检索三个参数?

问题描述 投票:3回答:2

我试图从文本中获取所有出现的代码片段和3个参数。我使用正则表达式和preg_match_all PHP函数执行此操作。

如果我只有一次出现在文本中的片段,它工作正常。如果有两个或更多我得到一个奇怪的结果。

我对正则表达式并不那么专业,所以我很难理解我错过了什么。

功能

public function getGallerySnippetOccurrences($text) {

    $ptn = '/{# +gallery +(src|width|height)=\[(.*)\] +(src|width|height)=\[(.*)\] +(src|width|height)=\[(.*)\] +#}/';

    if(preg_match_all($ptn,$text,$matches)){
        $turnedMatches = $this->turn_array($matches);
        return $turnedMatches;
    }
    else {
        return null;
    }
}

文本1(在这种情况下按预期工作)

Lorem ipsum {# gallery src=[holiday_images/london] width=[400] height=[300] #} sid amet.

返回:

array(1) {
  [0] =>
  array(7) {
    [0] =>
    string(66) "{# gallery src=[holiday_images/london] width=[400] height=[300] #}"
    [1] =>
    string(3) "src"
    [2] =>
    string(21) "holiday_images/london"
    [3] =>
    string(5) "width"
    [4] =>
    string(3) "400"
    [5] =>
    string(6) "height"
    [6] =>
    string(3) "300"
  }
}

文字2(意外行为)

Lorem ipsum {# gallery src=[holiday_images/london] width=[400] height=[300] #} sid amet {# gallery src=[holiday_images/paris] width=[400] height=[300] #}

返回

array(1) {
  [0] =>
  array(7) {
    [0] =>
    string(141) "{# gallery src=[holiday_images/london] width=[400] height=[300] #} sid amet {# gallery src=[holiday_images/paris] width=[400] height=[300] #}"
    [1] =>
    string(3) "src"
    [2] =>
    string(96) "holiday_images/london] width=[400] height=[300] #} sid amet {# gallery src=[holiday_images/paris"
    [3] =>
    string(5) "width"
    [4] =>
    string(3) "400"
    [5] =>
    string(6) "height"
    [6] =>
    string(3) "300"
  }
}

我究竟做错了什么?

php regex
2个回答
1
投票

正如我在下面的评论中指出的那样,使量词非贪婪的答案将使其发挥作用。但是,这仍然会使您的正则表达式重复且效率低下。

您可以考虑这两种方法:

$re = '/{\#
\h+gallery
\h+(src|width|height)=\[([^]]*)]
\h+((?1))=\[([^]]*)]
\h+((?1))=\[([^]]*)]
\h*\#}/x';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

// Print the entire match result
var_dump($matches); 

RegEx Demo

  • 注意这个正则表达式如何定义子模式并使用(?1)重复使用正则表达式来避免重复
  • 还要注意使用更有效的否定类[^]]*而不是低效的.*?来捕获值。

2
投票

在你的模式中,你使用(。)使用贪婪匹配,应该用非贪婪模式(。?)替换。请在下面找到模式

$ptn = '/{# +gallery +(src|width|height)=\[(.*?)\] +(src|width|height)=\[(.*?)\] +(src|width|height)=\[(.*?)\] +#}/';
© www.soinside.com 2019 - 2024. All rights reserved.