在字符串中查找出现的字符串并替换 - php
Find occurences of strings in string and replace - php
我目前正在制作我的自制 headline-system。因此,我尝试在文本中使用 #_1#
- #_4#
进行编号,然后应将其转换为标题。因此,您将标题的文本写在数字和第二个 #
之间。例如:
#_1Testheadline#
#_2second headline under the first one#
#_2another headline under the first one#
#_1second headline (not under the first one)#
会变成
1. Testheadline
1.1 second headline under the first one
1.2 another headline under the first one
2. second headline (not under the first one)
希望你明白我的意思。
所以第一个例子(所以里面有#_1#
)写在WYSIWYG-Editor里,所以这是正常的html代码,然后存储在一个变量里数据库。
我现在想要的是当我从数据库中获取这个变量时,我想用真正的标题替换所有pseudo-headlines(以查看),所以第一个示例将成为第二个。
因此我需要找到所有出现的 #_1
,替换为 <h1>
,继续直到 #
并将其替换为 </h1>
。标题的第二个、第三个和第四个 "layer" 相同。如果我能做到这一点,我仍然不会完成,因为现在,标题需要在前面加上数字,因此我可以简单地使用 4 个计数器:
var firstlayercount = 0,
secondlayercount = 0;
var thirdlayercount = 0,
fourthlayercount = 0;
然后增加并将它们设置回 0,具体取决于找到的标题,所以实际上这应该是更容易的部分。但更难的问题是,如何找到字符串中的 #_1
,替换它然后再去 #
也替换它?并多次这样做?
使用preg_replace_callback函数
$str = '#_1Testheadline#
#_2second headline under the first one
#_2another headline under the first one
#_1second headline (not under the first one)';
// Current level
$level = 0;
echo preg_replace_callback('/#?\s*#_(\d)+/',
function($x) use (&$level) {
// Close previous tag if it is
$out = ($level ? "</h{$level}>\n" : '');
// Save current level and open tag
$level = $x[1];
return $out . "<h{$level}>";
},
// Don't forget to close the last tag
$str) . "<h{$level}>";
结果
<h1>Testheadline#</h1>
<h2>second headline under the first one</h2>
<h2>another headline under the first one</h2>
<h1>second headline (not under the first one)<h1>
更新 1
您可以使用相同的方法来构建有序列表
$level = 0;
echo preg_replace_callback('/#?\s*#_(\d)+/',
function($x) use (&$level) {
if($x[1] > $level) $out = "\n<ol>\n";
else if ($x[1] < $level) $out = "</li>\n</ol>\n";
else $out = "</li>\n";
$level = $x[1];
return $out . "<li>";
},
$str) . "</li>\n</ol>\n";
结果
<ol>
<li>Testheadline#
<ol>
<li>second headline under the first one</li>
<li>another headline under the first one</li>
</ol>
<li>second headline (not under the first one)</li>
</ol>
更新 2
按 css
风格化列表
<STYLE>
ol {
list-style: none;
counter-reset: li;
}
li:before {
counter-increment: li;
content: counters(li,".") ". ";
}
</STYLE>
<ol>
<li>Testheadline#
<ol>
<li>second headline under the first one</li>
<li>another headline under the first one</li>
</ol>
<li>second headline (not under the first one)</li>
</ol>
更新 3
按php
进行编号
$cnts = [ 0 ];
echo preg_replace_callback('/#?\s*#_(\d)+/',
function($x) use (&$cnts) {
$level = $x[1]-1;
if($level < count($cnts)-1) $cnts = array_slice($cnts, 0, $level+1);
if (! isset($cnts[$level])) $cnts[$level] = 1;
else $cnts[$level]++;
$temp = array_slice($cnts, 0, $level+1);
return "\n" . implode('.', $temp) . ". ";
},
$str) ;
结果
1. Testheadline
1.1. second headline under the first one
1.2. another headline under the first one
2. second headline (not under the first one)
我目前正在制作我的自制 headline-system。因此,我尝试在文本中使用 #_1#
- #_4#
进行编号,然后应将其转换为标题。因此,您将标题的文本写在数字和第二个 #
之间。例如:
#_1Testheadline#
#_2second headline under the first one#
#_2another headline under the first one#
#_1second headline (not under the first one)#
会变成
1. Testheadline
1.1 second headline under the first one
1.2 another headline under the first one
2. second headline (not under the first one)
希望你明白我的意思。
所以第一个例子(所以里面有#_1#
)写在WYSIWYG-Editor里,所以这是正常的html代码,然后存储在一个变量里数据库。
我现在想要的是当我从数据库中获取这个变量时,我想用真正的标题替换所有pseudo-headlines(以查看),所以第一个示例将成为第二个。
因此我需要找到所有出现的 #_1
,替换为 <h1>
,继续直到 #
并将其替换为 </h1>
。标题的第二个、第三个和第四个 "layer" 相同。如果我能做到这一点,我仍然不会完成,因为现在,标题需要在前面加上数字,因此我可以简单地使用 4 个计数器:
var firstlayercount = 0,
secondlayercount = 0;
var thirdlayercount = 0,
fourthlayercount = 0;
然后增加并将它们设置回 0,具体取决于找到的标题,所以实际上这应该是更容易的部分。但更难的问题是,如何找到字符串中的 #_1
,替换它然后再去 #
也替换它?并多次这样做?
使用preg_replace_callback函数
$str = '#_1Testheadline#
#_2second headline under the first one
#_2another headline under the first one
#_1second headline (not under the first one)';
// Current level
$level = 0;
echo preg_replace_callback('/#?\s*#_(\d)+/',
function($x) use (&$level) {
// Close previous tag if it is
$out = ($level ? "</h{$level}>\n" : '');
// Save current level and open tag
$level = $x[1];
return $out . "<h{$level}>";
},
// Don't forget to close the last tag
$str) . "<h{$level}>";
结果
<h1>Testheadline#</h1>
<h2>second headline under the first one</h2>
<h2>another headline under the first one</h2>
<h1>second headline (not under the first one)<h1>
更新 1
您可以使用相同的方法来构建有序列表
$level = 0;
echo preg_replace_callback('/#?\s*#_(\d)+/',
function($x) use (&$level) {
if($x[1] > $level) $out = "\n<ol>\n";
else if ($x[1] < $level) $out = "</li>\n</ol>\n";
else $out = "</li>\n";
$level = $x[1];
return $out . "<li>";
},
$str) . "</li>\n</ol>\n";
结果
<ol>
<li>Testheadline#
<ol>
<li>second headline under the first one</li>
<li>another headline under the first one</li>
</ol>
<li>second headline (not under the first one)</li>
</ol>
更新 2
按 css
风格化列表<STYLE>
ol {
list-style: none;
counter-reset: li;
}
li:before {
counter-increment: li;
content: counters(li,".") ". ";
}
</STYLE>
<ol>
<li>Testheadline#
<ol>
<li>second headline under the first one</li>
<li>another headline under the first one</li>
</ol>
<li>second headline (not under the first one)</li>
</ol>
更新 3
按php
进行编号$cnts = [ 0 ];
echo preg_replace_callback('/#?\s*#_(\d)+/',
function($x) use (&$cnts) {
$level = $x[1]-1;
if($level < count($cnts)-1) $cnts = array_slice($cnts, 0, $level+1);
if (! isset($cnts[$level])) $cnts[$level] = 1;
else $cnts[$level]++;
$temp = array_slice($cnts, 0, $level+1);
return "\n" . implode('.', $temp) . ". ";
},
$str) ;
结果
1. Testheadline
1.1. second headline under the first one
1.2. another headline under the first one
2. second headline (not under the first one)