- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在努力弄清楚如何使用 preg_match_all 和 PREG_OFFSET_CAPTURE 解析音乐(文本)标签。
Example输入:
[D#] [G#] [Fm]
[C#] [Fm] [C#] [Fm] [C#] [Fm]
[C]La la la la la la [Fm]la la la la [D#]
[Fm]I made this song Cause I [Bbm]love you
[C]I made this song just for [Fm]you [D#]
[Fm]I made this song deep in [Bbm]my heart
我想要得到的输出:
D# G# Fm
C# Fm C# Fm C# Fm
C Fm D#
La la la la la la la la la la
Fm Bbm
I made this song Cause I love you
C Fm D#
I made this song just for you
Fm Bbm
I made this song deep in my heart
最后,我想用 html 标签包裹和弦。
请注意,和弦之间的空格应与原始输入中这些和弦的位置完全匹配。
我开始逐行解析输入,检测和弦,获取它们的位置,......但我的代码不起作用......我的函数 line_extract_chords 有问题,它无法正常工作。
有什么想法吗?
<style>
body{
font-family: monospace;
white-space: pre;
</style>
<?php
function parse_song($content){
$lines = explode(PHP_EOL, $content); //explode lines
foreach($lines as $key=>$line){
$chords_line = line_extract_chords($line);
$lines[$key] = implode("\n\r",(array)$chords_line);
}
return implode("\n\r",$lines);
}
function line_extract_chords($line){
$line_chords = null; //text line with chords, used to compute offsets
$line_chords_html = null; //line with chords links
$found_chords = array();
$line = html_entity_decode($line); //remove special characters (would make offset problems)
preg_match_all("/\[([^\]]*)\]/", $line, $matches, PREG_OFFSET_CAPTURE);
$chord_matches = array();
if ( $matches[1] ){
foreach($matches[1] as $key=>$chord_match){
$chord = $chord_match[0];
$position = $chord_match[1];
$offset= $position;
$offset-= 1; //left bracket
$offset-=strlen($line_chords); //already filled line
//previous matches
if ($found_chords){
$offset -= strlen(implode('',$found_chords));
$offset -= 2*(count($found_chords)); //brackets for previous chords
}
$chord_html = '<a href="#">'.$chord.'</a>';
//add spaces
if ($offset>0){
$line_chords.= str_repeat(" ", $offset);
$line_chords_html.= str_repeat(" ", $offset);
}
$line_chords.=$chord;
$line_chords_html.=$chord_html;
$found_chords[] = $chord;
}
}
$line = htmlentities($line); //revert html_entity_decode()
if ($line_chords){
$line = preg_replace('/\[([^\]]*)\]/', '', $line);
return array($line_chords_html,$line);
}else{
return $line;
}
}
?>
最佳答案
我想提出一个更简单的方法。它基于这样的假设,即输入数据实际上与您在此处描述的一样一般可解析。
<style>
.line{
font-family: monospace;
white-space: pre;
margin-bottom:0.75rem;
}
.group{
display: inline-block;
margin-right: 0.5rem;
}
.group .top,
.group .top{
display: block;
}
</style>
<?php
$input = "[D#] [G#] [Fm]
[C#] [Fm] [C#] [Fm] [C#] [Fm]
[C]La la la la la la [Fm]la la la la [D#]
[Fm]I made this song Cause I [Bbm]love you
[C]I made this song just for [Fm]you [D#]
[Fm]I made this song deep in [Bbm]my heart";
$output = '';
$inputLines = explode(PHP_EOL,$input);
foreach($inputLines as $line){
$output .='<div class="line">';
if (!strlen($line)){
$output .= ' ';
}
else{
$inputWords = explode(' ',$line);
foreach($inputWords as $word){
if (preg_match('/^\[(.+)\](.+)$/', $word, $parts)){
$output .='<span class="group"><span class="top">'.$parts[1].'</span><span class="bottom">'.$parts[2].'</span></span>';
}
elseif(preg_match('/^\[(.+)\]$/', $word, $parts)){
$output .='<span class="group"><span class="top">'.$parts[1].'</span><span class="bottom"> </span></span>';
}
else{
$output .='<span class="group"><span class="top"> </span><span class="bottom">'.$word.'</span></span>';
}
}
}
$output .='</div>';
}
die ($output);
这里做的事情很简单。该脚本仅通过将其包装在 HTML 中来赋予和弦数据意义。定位和表示是用 CSS 定义的。
它还表明您在将示例和弦转换为示例输出的方式上存在一点错误。 Fm D#
第 5 行似乎有一点偏差。至少我希望如此。
添加:
为什么您的代码不起作用。
确实如此。不起作用的是它的介绍。你数了一行中的字母,并在另一行中用空格替换了它。有两件事在这里不起作用:
那你会怎么做呢?
white-space: pre;
设置为一种样式,以便真正识别空白。font-family: monospace;
) 以确保您的替换字体对齐。就是这样:
<style>
body{
font-family: monospace;
white-space: pre;
</style>
<?php
function parse_song($content){
$lines = explode(PHP_EOL, $content); //explode lines
foreach($lines as $key=>$line){
$chords_line = line_extract_chords($line);
$lines[$key] = implode("\n\r",(array)$chords_line);
}
return implode("\n\r",$lines);
}
function line_extract_chords($line){
$line_chords = null; //text line with chords, used to compute offsets
$line_chords_html = null; //line with chords links
$found_chords = array();
$line = html_entity_decode($line); //remove special characters (would make offset problems)
preg_match_all("/\[([^\]]*)\]/", $line, $matches, PREG_OFFSET_CAPTURE);
$chord_matches = array();
if ( $matches[1] ){
foreach($matches[1] as $key=>$chord_match){
$chord = $chord_match[0];
$position = $chord_match[1];
$offset= $position;
$offset-= 1; //left bracket
$offset-=strlen($line_chords); //already filled line
//previous matches
if ($found_chords){
$offset -= strlen(implode('',$found_chords));
$offset -= 2*(count($found_chords)); //brackets for previous chords
}
$chord_html = '<a href="#">'.$chord.'</a>';
//add spaces
if ($offset>0){
$line_chords.= str_repeat(" ", $offset);
$line_chords_html.= str_repeat(" ", $offset);
}
$line_chords.=$chord;
$line_chords_html.=$chord_html;
$found_chords[] = $chord;
}
}
$line = htmlentities($line); //revert html_entity_decode()
if ($line_chords){
$line = preg_replace('/\[([^\]]*)\]/', '', $line);
return array($line_chords_html,$line);
}else{
return $line;
}
}
$input = "[D#] [G#] [Fm]
[C#] [Fm] [C#] [Fm] [C#] [Fm]
[C]La la la la la la [Fm]la la la la [D#]
[Fm]I made this song Cause I [Bbm]love you
[C]I made this song just for [Fm]you [D#]
[Fm]I made this song deep in [Bbm]my heart";
die(parse_song($input));
我删除了 self::
引用以使其独立工作。
所以您实际上并没有在此处编写任何错误代码。你只是搞砸了结果的呈现。
尽管如此,您最终还是得到了一段毫无意义、几乎无法解析(可能是为了解释)的文本。解析输入的步骤应着重于赋予数据意义。例如,如果那是 HTML 或 XML 标记甚至 JSON 的方式,都没有关系。但是您应该将纯文本转换为结构化数据。
这样你就可以很容易地设计它。您可以识别整个结构的单个部分或过滤掉它们。
关于php - 使用 PHP 从选项卡中提取和弦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33770714/
我使用Andrew的d3和弦图示例并希望将弯曲切片内的所有文本标签居中。我尝试了很多东西,但始终无法将文本居中。你知道需要什么巫师技巧吗? var width = 720, height = 720,
我正在尝试实现一个系统,在该系统中我可以同时播放一组频率,目前可以单独播放每个频率。下面我有一个代码,它播放给定的频率,一次播放一个。 import java.applet.*; im
是否可以一次重新映射使用 ctrl+k 作为第一个按键操作的所有和弦? 我使用 ctrl+k 删除该行的其余部分。由于它与 vscode 中使用的最常见和弦冲突,因此通过快捷方式重新映射快捷方式会很不
我是一名优秀的程序员,十分优秀!