如何在进入不同步骤/数组/位置的两个标签之间捕获多行正则表达式

时间:2019-05-24 10:19:11

标签: php regex tags tcpdf

我使用TCPDF生成一些复杂的PDF,因此问题出在PDF内部而不是标准网页

我正在尝试在2个标签之间获取文本,其中包括[#SCHANGE#][#ECHANGE#]这两个标签。

我正在使用此正则表达式:

preg_match('/(?:\[#SCHANGE#\]((?:.*?\r?\n?)*)\[#ECHANGE#\])+/m', $textV, $StartEndChange);

$textV是一个动态值,它来自诸如以下的foreach循环:

foreach($text as $textV){

    //some code here..

}

内部可能有不同的情况,例如:

$text = array (
    "0" => "[#SCHANGE#] same text [#ECHANGE#]" //This is okay, regex works in this case
) ;

但是当在$text中只有一个标签时,此正则表达式无法正常工作:

$text = array (
    "0" => "[#SCHANGE#]same text",
    "1" => "some text",
    "2" => "some text",
    "3" => "some text",
    "4" => "some text",
    "5" => "some text",
    "6" => "some text",
    "7" => "some text [#ECHANGE#]"
) ;

所以:如果标签不在同一文本中,我如何才能获得包括两个标签在内的2个标签之间的文本?

我无法爆炸数组,因为$text中的所有文本都已格式化,并且可以与上一个或下一个不同地打印

3 个答案:

答案 0 :(得分:1)

您的原始表达非常接近。我们可能只想将(\[#SCHANGE#\])(\[#ECHANGE#\])作为左右边界,然后收集我们的“某些文本”,也许使用类似于以下内容的表达式:

(\[#SCHANGE#\])(.+?)(\[#ECHANGE#\])

测试

$re = '/(\[#SCHANGE#\])(.+?)(\[#ECHANGE#\])/m';
$str = '[#SCHANGE#] same text 1 [#ECHANGE#]
[#SCHANGE#] same text 2 [#ECHANGE#]
[#SCHANGE#] same text 3 [#ECHANGE#]
[#SCHANGE#] same text 4 [#ECHANGE#][#SCHANGE#] same text 5 [#ECHANGE#]';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
$arr = array();
foreach ($matches as $key => $value) {$arr[$key] = $value[0];}
var_dump($arr);

输出

array(5) {
  [0]=>
  string(35) "[#SCHANGE#] same text 1 [#ECHANGE#]"
  [1]=>
  string(35) "[#SCHANGE#] same text 2 [#ECHANGE#]"
  [2]=>
  string(35) "[#SCHANGE#] same text 3 [#ECHANGE#]"
  [3]=>
  string(35) "[#SCHANGE#] same text 4 [#ECHANGE#]"
  [4]=>
  string(35) "[#SCHANGE#] same text 5 [#ECHANGE#]"
}

RegEx

如果不需要此表达式,可以在regex101.com中对其进行修改或更改。

enter image description here

RegEx电路

jex.im可视化正则表达式:

enter image description here

答案 1 :(得分:1)

我会先内爆数组,然后在字符串中搜索:

$text = array (
    "[#SCHANGE#]same text",
    "some text",
    "some text",
    "some text",
    "some text",
    "some text",
    "some text",
    "some text [#ECHANGE#]",
    "blah blah",
    "[#SCHANGE#]other text[#ECHANGE#]"
) ;

$all_text = implode("\n", $text);
preg_match_all('/\[#SCHANGE#\][\s\S]+?\[#ECHANGE#\]/', $all_text, $matches);
print_r($matches);

输出:

Array
(
    [0] => Array
        (
            [0] => [#SCHANGE#]same text
some text
some text
some text
some text
some text
some text
some text [#ECHANGE#]
            [1] => [#SCHANGE#]other text[#ECHANGE#]
        )

)

答案 2 :(得分:1)

尝试一下:

$re = '/(\[#SCHANGE#\](.+?)\[#ECHANGE#\])|(\[#SCHANGE#\](.+?$))|(^(.+?)\[#ECHANGE#\])/m';

$str = '[#SCHANGE#]same text
some text [#ECHANGE#]
[#SCHANGE#] same text [#ECHANGE#]';

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

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

RegEx

如果不需要此表达式,可以在regex101.com中对其进行修改或更改。