Regex find specific words within a string

Well, I've searched and tested but don't know how to do the following:

I have this text:

*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]

      

And I need to find all words inside [], but only from the line starting with "|"

I know that using:

^\|.*

      

Find lines from start to end and using:

\[(.*?)\]

      

Will select all brackets and its contents, but I don't know how to say

Find this ^\|.*

and the result, apply this\[(.*?)\]

Why not step by step? because I would like to use preg_replace to wrap this word with HTML tags.

Am I even taking the right approach?

Many thanks.

+3


source to share


3 answers


Since you are dealing with plain text, you can use the following regex on it:

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

      

See regex demo

More details

  • (?:\G(?!\A)|^\|)

    - either the end of the previous match ( \G(?!\A)

    , \G

    matches both the beginning of the line and the end of the previous match, so the first position must be subtracted using a negative form (?!\A)

    - not at the beginning of the line) or ( |

    ) the beginning of the line ( ^

    ) followed by a letter |

    ( ^\|

    )
  • [^][\r\n]*

    - zero or more characters besides [

    , ]

    , CR and LF (to remain in one line)
  • \K

    - match the reset statement, omitting the text matched so far
  • \[

    - a [

  • (.*?)

    - any 0+ characters other than line break characters, as few as possible up to the first
  • ]

    - letter ]

    .

Another approach is to use preg_replace_callback

with a regex that matches all strings starting with |

and replace all substrings inside the callback function [...]

.



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

      

See PHP demo :

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

      

Output:

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

      

+3


source


You seem to be targeting substrings between square brackets that follow |

or –

, so this is my pattern (with optional trailing space):

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

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

Sample / Replacement Demo



PHP implementation: ( 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);

      

Output:

*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


source


Using backtracking control verbs to skip lines starting with a character that is not |

:

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

      

demo

0


source







All Articles