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

时间:2017-07-13 20:52:30

标签: php regex

好吧,我正在搜索和测试,但我不知道如何执行以下操作:

我有这样的文字:

*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标签包装单词。

我是否采取了正确的方法?

非常感谢。

3 个答案:

答案 0 :(得分:3)

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

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

请参阅regex demo

<强>详情:

  • (?:\G(?!\A)|^\|) - 上一场比赛的结尾(\G(?!\A)\G匹配字符串的开头和上一场比赛的结尾,因此应使用第一个位置减去第一个位置否定前瞻(?!\A) - 不在字符串的开头)或(|)行的开头(^)后面跟着文字{{1 (|
  • ^\| - 除[^][\r\n]*[,CR和LF之外的零个或多个字符(保持在同一行)
  • ] - 匹配重置运算符,省略目前为止匹配的文本
  • \K - \[
  • [ - 除了换行符之外的任何0 +字符尽可能少到第一个字符
  • (.*?) - 文字]

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

[...]

请参阅PHP demo

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

输出:

$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);

答案 1 :(得分:0)

您好像是在|之后的方括号之间定位子字符串,所以这就是我的模式所做的(带有可选的尾随空格):

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

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

Pattern/Replacement Demo

PHP实施:(Demo

$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>

答案 2 :(得分:0)

使用回溯控制动词来跳过以不是|的字符开头的行:

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

demo