如何使用与 PHP str_replace 相同的字符串(字符)来打开和关闭标签?
How to use same string (character) with PHP str_replace to open and close tag?
我需要让我网站上的成员能够使用字符串 ` 输入代码并使用相同的字符串 ` 关闭它,就像我们在 Whosebug 中所做的那样。
这是我用过的代码
function replace_text($text) {
$text = str_replace('`', '<code>', $text);
$text = str_replace('`', '<\code>', $text);
return $text;
}
add_filter('the_content', 'replace_text');
问题是只有第一个字符串 ` 被替换,然后 <code>
标签没有关闭。
您可以尝试使用 preg_replace
代替:
function replace_text($text) {
return preg_replace('/`([^`]*)`/', '<code></code>', $text);
}
例如:
$text = 'some words and `some code` and some more words';
echo replace_text($text);
输出:
some words and <code>some code</code> and some more words
更新
如果您担心文本中存在转义反引号的可能性,您可以改用此正则表达式,它会使用负向后视检查第一个反引号是否未转义,然后忽略分隔符:
function replace_text($text) {
return preg_replace('/(?<!\\)`((?:[^`\\]|\\.)*)`/', '<code></code>', $text);
}
另一个例子:
$text = 'some words \` and `some code` and `some \`more code` again';
echo replace_text($text);
输出:
some words \` and <code>some code</code> and <code>some \`more code</code> again
更新 2
为了也替换字符串中的任何 \`
,我们在对 preg_match
的调用中添加第二对模式和替换:
function replace_text($text) {
return preg_replace(array('/(?<!\\)`((?:[^`\\]|\\.)*)`/', '/\\`/'), array('<code></code>', '`'), $text);
}
$text = 'some words \` and `some code` and `some \`more code` again';
echo replace_text($text);
输出:
some words ` and <code>some code</code> and <code>some `more code</code> again
按照这些思路应该可以工作 - 它避免了正则表达式的性能开销(如果你关心这类事情)并且如果你有未关闭的块可以提供反馈:
while (strpos($text, '`')) {
$firstOccurence = strpos($text, '`');
$text = substr_replace($text, '<code>', $firstOccurence, 1);
$secondOccurence = strpos($text, '`');
if ($secondOccurence !== false) {
$text = substr_replace($text, '</code>', $secondOccurence, 1);
} else {
throw new Exception('Unclosed block');
}
}
此处示例:
https://repl.it/@abulafia/SparseLoathsomeExtensions
这将在找到刻度时继续解析文本。 str_pos
标识第一个刻度的位置,然后我们使用 substr_replace
替换它。然后我们重复这个过程,但是如果没有第二个刻度,抛出一个异常(或者做任何你想做的事!)
我会以一种尊重代码也可能包含一些反引号的可能性的方式来做。
为此,您可以使用带有捕获组和反向引用的正则表达式。第一个捕获组 (`+)
至少需要一个反引号,并且尽可能多地用于量词 +
。然后在第 2 组中捕获以下所有字符。反向引用 </code>(使用转义反斜杠编码的字符串 <code>'\1'
)需要与第 1 组中捕获的一样多的反引号。
$s = 'Some ``code containing the backtick ` character`` should `work` as well.';
$tagged = preg_replace('~(`+)(.*?)\1~us', '<code></code>', $s);
结果:
Some <code>code containing the backtick ` character</code> should <code>work</code> as well.
但是,我建议使用完整的 markdown 解析器,可以在网上找到作为开源库。
我需要让我网站上的成员能够使用字符串 ` 输入代码并使用相同的字符串 ` 关闭它,就像我们在 Whosebug 中所做的那样。
这是我用过的代码
function replace_text($text) {
$text = str_replace('`', '<code>', $text);
$text = str_replace('`', '<\code>', $text);
return $text;
}
add_filter('the_content', 'replace_text');
问题是只有第一个字符串 ` 被替换,然后 <code>
标签没有关闭。
您可以尝试使用 preg_replace
代替:
function replace_text($text) {
return preg_replace('/`([^`]*)`/', '<code></code>', $text);
}
例如:
$text = 'some words and `some code` and some more words';
echo replace_text($text);
输出:
some words and <code>some code</code> and some more words
更新
如果您担心文本中存在转义反引号的可能性,您可以改用此正则表达式,它会使用负向后视检查第一个反引号是否未转义,然后忽略分隔符:
function replace_text($text) {
return preg_replace('/(?<!\\)`((?:[^`\\]|\\.)*)`/', '<code></code>', $text);
}
另一个例子:
$text = 'some words \` and `some code` and `some \`more code` again';
echo replace_text($text);
输出:
some words \` and <code>some code</code> and <code>some \`more code</code> again
更新 2
为了也替换字符串中的任何 \`
,我们在对 preg_match
的调用中添加第二对模式和替换:
function replace_text($text) {
return preg_replace(array('/(?<!\\)`((?:[^`\\]|\\.)*)`/', '/\\`/'), array('<code></code>', '`'), $text);
}
$text = 'some words \` and `some code` and `some \`more code` again';
echo replace_text($text);
输出:
some words ` and <code>some code</code> and <code>some `more code</code> again
按照这些思路应该可以工作 - 它避免了正则表达式的性能开销(如果你关心这类事情)并且如果你有未关闭的块可以提供反馈:
while (strpos($text, '`')) {
$firstOccurence = strpos($text, '`');
$text = substr_replace($text, '<code>', $firstOccurence, 1);
$secondOccurence = strpos($text, '`');
if ($secondOccurence !== false) {
$text = substr_replace($text, '</code>', $secondOccurence, 1);
} else {
throw new Exception('Unclosed block');
}
}
此处示例:
https://repl.it/@abulafia/SparseLoathsomeExtensions
这将在找到刻度时继续解析文本。 str_pos
标识第一个刻度的位置,然后我们使用 substr_replace
替换它。然后我们重复这个过程,但是如果没有第二个刻度,抛出一个异常(或者做任何你想做的事!)
我会以一种尊重代码也可能包含一些反引号的可能性的方式来做。
为此,您可以使用带有捕获组和反向引用的正则表达式。第一个捕获组 (`+)
至少需要一个反引号,并且尽可能多地用于量词 +
。然后在第 2 组中捕获以下所有字符。反向引用 </code>(使用转义反斜杠编码的字符串 <code>'\1'
)需要与第 1 组中捕获的一样多的反引号。
$s = 'Some ``code containing the backtick ` character`` should `work` as well.';
$tagged = preg_replace('~(`+)(.*?)\1~us', '<code></code>', $s);
结果:
Some <code>code containing the backtick ` character</code> should <code>work</code> as well.
但是,我建议使用完整的 markdown 解析器,可以在网上找到作为开源库。