preg_replace 两个标签之间只有几个字符

preg_replace few chars between two tags

this is text before the tag \r \t
    \begin{aligned}\t \r \r
    \left(\frac{130}{100}x\right)  \t
    \end{aligned}
this is text after the tag \r \t 

我想删除 \begin\end 之间出现的所有 \r\t\n。我怎样才能使用 preg_replace.

按照OP的说明,这里的\r\n\t是字面量,不能和对应的特殊字符混淆。

<?php
$str = <<<'EOT'
this is text before the tag \r \t
    \begin{aligned}\t \r \r
    \left(\frac{130}{100}x\right)  \t
    \end{aligned}
this is text after the tag \r \t
\begin another \r\n\t\end
EOT;

echo
    '<pre>' .
    preg_replace_callback(
        '#\\begin.*?\\end#s', // The regular expression
        function ($matches) {
            return str_replace(array('\t', '\r', '\n'), '', $matches[0]); // removes all the specified literals
        },
        $str
    ) .
    '</pre>';
?>

正则表达式中<a href="http://php.net/manual/en/function.preg-replace-callback.php" rel="nofollow">preg_replace_callback()</a> matches all the text between the \begin and \end strings (inclusive). Having the s modifier in the pattern causes the dot metacharacter不排除换行符。

对于找到的每个匹配项,该函数都会调用第二个参数中指定的匿名函数,该函数会调用 <a href="http://php.net/manual/en/function.str-replace.php" rel="nofollow">str_replace()</a> 函数来删除文字。

输出:

this is text before the tag \r \t
    \begin{aligned}  
    \left(\frac{130}{100}xight)  
    \end{aligned}
this is text after the tag \r \t
\begin another \end

想法是使用 \G 锚点来仅获取连续的结果。当达到 \end 时,连续性被破坏。第一场比赛从分支 (1) 开始。

$str = <<<'EOD'
this is text before the tag \r \t
    \begin{aligned}\t \r \r
    \left(\frac{130}{100}x\right)  \t
    \end{aligned}
this is text after the tag \r \t 
EOD;

$pattern = <<<'EOD'
~
(?:
    \G(?!\A) # other occurrences are contiguous (2)
  |
    \begin\b # the first occurrence of \t \r or \n follows "\begin" (1)
)
[^\]* # all that is not a slash
(?:
    \ (?!(?:[trn]|end)\b) # a slash not followed by "t","r","n" or "end"
    [^\]*
)* (*SKIP)
\K # remove all characters on the left from the whole match
\ [trn]
~xS
EOD;

$result = preg_replace($pattern, '', $str);

如果将 \begin\b 更改为 [^\]*(?:\(?!begin\b)[^\]*)*+\begin\b

,您可以改进模式