GenesisBits
GenesisBits

Reputation: 346

Match everything in brackets after a specific character

I have the following string:

$text = 'These are my cards. They are {{Archetype|Agumon}} and {{Fire|Gabumon}}'

I'm trying to replace all instances of occurrences like {{Archetype|Agumon}} into [Agumon].

I've been struggling to get my head around it and have come up with this so far:

$string = preg_replace('#\{\{(.*?)\}\}#', '[$1]', $text);

This results in:

These are my cards. They are [Archetype|Agumon] and [Fire|Gabumon]

So I am currently matching the full text found in between the double curly brackets.

I thought it would be something like this: \|(.*?) to get the match after the | character in the curly brackets but to no avail.

Upvotes: 1

Views: 41

Answers (2)

Ryszard Czech
Ryszard Czech

Reputation: 18611

Use

preg_replace('/{{(?:(?!{|}})[^|]*\|(.*?))}}/s', '[$1]', $text)

See proof. It will support { and } in the part before the pipe.

Explanation

--------------------------------------------------------------------------------
  {{                       '{{'
--------------------------------------------------------------------------------
  (?:                      group, but do not capture:
--------------------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
      {                        '{'
--------------------------------------------------------------------------------
     |                        OR
--------------------------------------------------------------------------------
      }}                       '}}'
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
    [^|]*                    any character except: '|' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \|                       '|'
--------------------------------------------------------------------------------
    (                        group and capture to \1:
--------------------------------------------------------------------------------
      .*?                      any character (0 or more
                               times (matching the least amount
                               possible))
--------------------------------------------------------------------------------
    )                        end of \1
--------------------------------------------------------------------------------
  )                        end of grouping
--------------------------------------------------------------------------------
  }}                       '}}'

PHP code:

$text = 'These are my cards. They are {{Archetype|Agumon}} and {{Fire|Gabumon}}';
echo preg_replace('/{{(?:(?!{|}})[^|]*\|(.*?))}}/s', '[$1]', $text);

Results: These are my cards. They are [Agumon] and [Gabumon]

Upvotes: 0

41686d6564
41686d6564

Reputation: 19641

You may use:

\{\{[^}]*\|([^}]*)\}\}

Demo.

Breakdown:

  • \{\{ - Match "{{" literally.
  • [^}]* - Greedily match zero or more characters other than '}'.
  • \| - Match a pipe character.
  • ([^}]*) - Match zero or more characters other than '}' and capture them in group 1.
  • \}\} - Match "}}" literally.

Upvotes: 2

Related Questions