在字符串中查找特定单词的正则表达式

3

嗯,我一直在搜索和测试,但我不知道如何做以下操作:

我有这段文字:

*Intro*
| [C][G][Am][F][Dm][G]

*VERSE 1*
=[C][G][Am]
=cu{a}nto he esp{e}rado este mo{m}ento
| [F][F][Dm][F][Dm][G]

我需要找到以"|"开头的行中所有[]内的单词。
我知道可以使用:
^\|.*

将从开始到结束找到这些行,并使用以下方法:
\[(.*?)\]

将选择所有括号及其内容,但我不知道如何表达。
找到这个^\|.*,并将结果应用于\[(.*?)\] 为什么不一步一步来?因为我想使用preg_replace将单词包装在HTML标记中。
我是否采取了正确的方法?
非常感谢。

HTML标签都是一样的吗?(例如<span></span>)请展示您期望的最终结果,包括标签。 - mickmackusa
这是我要寻找的结果 <span class="chord" data-original-title="" title="">C</span> - Rudy Palacios
你想要移除管道符号和方括号吗?请编辑你的问题以精确展示你想要基于所提供的输入得到的输出。 - mickmackusa
3个回答

3

由于您正在处理纯文本,因此可以对其使用以下正则表达式:

'~(?:\G(?!\A)|^\|)[^][\r\n]*\K\[(.*?)]~m'

请查看正则表达式演示

细节:

  • (?:\G(?!\A)|^\|) - 匹配前一个匹配的结尾(\G(?!\A), \G可以匹配字符串开头和前一个匹配的结尾,所以第一个位置应该使用负向先行断言匹配 (?!\A) - 不在字符串开头) 或者 (|) 在行首(^) 后跟一个直接量 | (^\|)
  • [^][\r\n]* - 除了 [, ], 回车符和换行符外的零个或多个字符(保持在同一行)
  • \K - 匹配重置运算符,省略到目前为止匹配的文本
  • \[ - 匹配一个 [
  • (.*?) - 尽可能少地匹配任意 0+ 个非换行符的字符,直到找到第一个
  • ] - 匹配一个字面上的 ]

另一种方法是使用具有匹配所有以 | 开始的行的正则表达式的 preg_replace_callback ,并在回调函数中替换所有 [...] 子字符串。

preg_replace_callback('~^\|.+~m', function ($m) {
        return preg_replace('~\[(.*?)]~', '<span class="chord" data-original-title="" title="">'.$m[1]."</span>", $m[0]);
    }, $s);

请查看PHP演示

$s = <<<TXT
*Intro*
| [C] – [G] – [Am] – [F] – [Dm] – [G]

*VERSE 1*
=[C][G][Am]
=cu{a}nto he esp{e}rado este mo{m}ento
| [F] – [F] – [Dm] – [F] – [Dm] – [G]
TXT;

echo preg_replace_callback('~^\|.+~m', function ($m) {
    return preg_replace('~\[(.*?)]~', '<span class="chord" data-original-title="" title="">$1</span>', $m[0]);
}, $s);

输出:

*Intro*
| <span class="chord" data-original-title="" title="">C</span> – <span class="chord" data-original-title="" title="">G</span> – <span class="chord" data-original-title="" title="">Am</span> – <span class="chord" data-original-title="" title="">F</span> – <span class="chord" data-original-title="" title="">Dm</span> – <span class="chord" data-original-title="" title="">G</span>

*VERSE 1*
=[C][G][Am]
=cu{a}nto he esp{e}rado este mo{m}ento
| <span class="chord" data-original-title="" title="">F</span> – <span class="chord" data-original-title="" title="">F</span> – <span class="chord" data-original-title="" title="">Dm</span> – <span class="chord" data-original-title="" title="">F</span> – <span class="chord" data-original-title="" title="">Dm</span> – <span class="chord" data-original-title="" title="">G</span>

1
我应该如何到达那个正则表达式?这个方法正好符合我的需求,非常感谢! - Rudy Palacios

0

看起来你的目标是方括号中跟随|的子字符串,因此这就是我的模式(带有可选的尾随空格):

模式:/([|–] )\[([^]]+)\]( ?)/

替换:$1<span class="chord" data-original-title="$2" title="$2">$2</span>$3

模式/替换演示

PHP实现:(演示

$txt='*Intro*
| [C] – [G] – [Am] – [F] – [Dm] – [G]

*VERSE 1*
=[C][G][Am]
=cu{a}nto he esp{e}rado este mo{m}ento
| [F] – [F] – [Dm] – [F] – [Dm] – [G]';
echo preg_replace('/([|–] )\[([^]]+)\]( ?)/','$1<span class="chord" data-original-title="$2" title="$2">$2</span>$3',$txt);

输出:

*Intro*
| <span class="chord" data-original-title="C" title="C">C</span> – <span class="chord" data-original-title="G" title="G">G</span> – <span class="chord" data-original-title="Am" title="Am">Am</span> – <span class="chord" data-original-title="F" title="F">F</span> – <span class="chord" data-original-title="Dm" title="Dm">Dm</span> – <span class="chord" data-original-title="G" title="G">G</span>

*VERSE 1*
=[C][G][Am]
=cu{a}nto he esp{e}rado este mo{m}ento
| <span class="chord" data-original-title="F" title="F">F</span> – <span class="chord" data-original-title="F" title="F">F</span> – <span class="chord" data-original-title="Dm" title="Dm">Dm</span> – <span class="chord" data-original-title="F" title="F">F</span> – <span class="chord" data-original-title="Dm" title="Dm">Dm</span> – <span class="chord" data-original-title="G" title="G">G</span>

0

使用回溯控制字符来跳过以非|字符开头的行:

preg_match_all('~^[^|\v].*\R*(*SKIP)(*F)|\[\K[^]]+~m', $text, $matches);
print_r($matches[0]);

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接