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
,您可以改进模式
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