我目前正在尝试这个PHP preg_replace
功能,但我遇到了一个小问题。我想用带有ID的div替换所有标签,每个div都是唯一的,所以我想我会把它添加到for循环中。但是以某种奇怪的方式,它只执行第一行并给它一个49的ID,这是他们可以获得的最后一个ID。这是我的代码:
$res = mysqli_query($mysqli, "SELECT * FROM song WHERE id = 1");
$row = mysqli_fetch_assoc($res);
mysqli_set_charset("utf8");
$lyric = $row['lyric'];
$lyricHTML = nl2br($lyric);
$lines_arr = preg_split('[<br />]',$lyricHTML);
$lines = count($lines_arr);
for($i = 0; $i < $lines; $i++) {
$string = preg_replace(']<br />]', '</h4><h4 id="no'.$i.'">', $lyricHTML, 1);
echo $i;
}
echo '<h4>';
echo $string;
echo '</h4>';
它的工作原理是我的数据库中有大量的文本,当我将它添加到lyric变量中时,它只是纯文本。但是当我知道它时,它会在每一行之后得到它,我在这里使用它。我通过使用小&#34; lines_arr&#34;得到了数量。你可以看到的方法,然后基本上迭代for循环。
唯一的问题是它只在第一行输出并且给出了49的ID。当我将它移到for循环之外并删除限制时,它可以工作,并且所有行都围绕它们获得<h4>
,但后来我没有得到我需要的唯一ID。
这是我从数据库中提取的一些文字
Mama called about the paper turns out they wrote about me
Now my broken heart´s the only thing that's broke about me
So many people should have seen what we got going on
I only wanna put my heart and my life in songs
Writing about the pain I felt with my daddy gone
About the emptiness I felt when I sat alone
About the happiness I feel when I sing it loud
He should have heard the noise we made with the happy crowd
Did my Gran Daddy know he taught me what a poem was
How you can use a sentence or just a simple pause
What will I say when my kids ask me who my daddy was
I thought about it for a while and I'm at a loss
Knowing that I´m gonna live my whole life without him
I found out a lot of things I never knew about him
All I know is that I´ll never really be alone
Cause we gotta lot of love and a happy home
我的目标是为每一行提供一个<h4 id="no1">TEXT</h4>
,no
之后的数字,如no1
或no4
应该每次迭代递增,&# 39;为什么我选择了for-loop。
答案 0 :(得分:2)
看起来你需要逃避你的正则表达式
preg_replace('/\[<br \/\]/', ...);
但实际上,这是一个经典的XY Problem。您应该问我们如何解决您的问题,而不是问我们如何解决您的解决方案。
向我们展示数据库中的一些示例文本,然后向我们展示您希望如何格式化它。它很可能是更好的方式。
我会使用array_walk。 ideone demo here
$lines = preg_split("/[\r\n]+/", $row['lyric']);
array_walk($lines, function(&$line, $idx) {
$line = sprintf("<h4 id='no%d'>%s</h4>", $idx+1, $line);
});
echo implode("\n", $lines);
输出
<h4 id="no1">Mama called about the paper turns out they wrote about me</h4>
<h4 id="no2">Now my broken heart's the only thing that's broke about me</h4>
<h4 id="no3">So many people should have seen what we got going on</h4>
...
<h4 id="no16">Cause we gotta lot of love and a happy home</h4>
解决方案的解释
nl2br在这里并没有真正帮助我们。它会将\n
转换为<br />
,但之后我们才会最终将字符串拆分为br。我们也可以先使用\n
进行拆分。我将使用/[\r\n]+/
,因为它会拆分一个或多个\r
,\n
和\r\n
。
$lines = preg_split("/[\r\n]+/", $row['lyric']);
现在我们有一个字符串数组,每个字符串包含一行歌词。但我们希望将每个字符串包装在<h4 id="noX">...</h4>
中,其中X是该行的编号。
通常我们会使用array_map,但array_map
回调不会收到索引参数。相反,我们将使用确实接收索引的array_walk。
关于这一行的另一个注意事项是使用&$line
作为回调参数。这允许我们改变$line
的内容并将其保存为#34;在我们原来的$lyrics
数组中。 (参见PHP文档中的示例#1来比较差异)。
array_walk($lines, function(&$line, $idx) {
这里是h4
的来源。我使用sprintf来格式化HTML字符串,因为我认为它们更具可读性。它允许您控制参数的输出方式,而无需在&#34;模板中添加一堆视图逻辑。
这是世界上最小的模板:'<h4 id="no%d">%s</h4>'
。它有两个输入%d
和%s
。第一个将作为数字(我们的行号)输出,第二个将作为字符串输出(我们的歌词)。
$line = sprintf('<h4 id="no%d">%s</h4>', $idx+1, $line);
关闭array_walk
回调函数
});
现在$lines
是我们新格式化歌词的数组。让我们通过用\n
分隔每一行来输出歌词。
echo implode("\n", $lines);
完成!
答案 1 :(得分:1)
如果db中的文本在每行中,为什么不用\ n字符爆炸它?
总是尝试在不使用preg功能集的情况下找到解决方案,因为它们是重度内存使用者:
我会去看看:
$lyric = $row['lyric'];
$lyrics =explode("\n",$lyrics);
$lyricsHtml=null;
$i=0;
foreach($lyrics as $val){
$i++;
$lyricsHtml[] = '<h4 id="no'.$i.'">'.$val.'</h4>';
}
$lyricsHtml = implode("\n",$lyricsHtml);
答案 2 :(得分:1)
preg_replace_callback
的另一种方式:
$id = 0;
$lyric = preg_replace_callback('~(^)|$~m',
function ($m) use (&$id) {
return (isset($m[1])) ? '<h4 id="no' . ++$id . '">' : '</h4>'; },
$lyric);