Skip to content
Advertisement

Extract and replace dynamic placeholders in javascript string

I need to understand and find a way to replace the occurences of placeholders in a string. I’m working on an app for the Magic, The Gathering tcg game. The text of the card contains a description and some symbols

Let me explain better with an example:

Some possible strings are “{W}{B}, {T}: Prevent all combat damage that would be dealt by target creature this turn.” “Flashback {2}{R} (You may cast this card from your graveyard for its flashback cost. Then exile it”

Those strings have to become an html text that Angular can then put inside the DOM. Each of those letters or numbers between curly brackets represent one different symbol to be printed. The possible symbols and the position of those can vary a lot. The text and position because each card is different and the symbol because there are about 1 hundred of possible symbols.

From the free Symbology API API that I’m using I have the association between the letter/number and it’s relative symbol image:

interface Symbols {
    ...
    svg_uri: string;
    symbol: string
    ...
}

This object is already mapped for each symbol. So I have a list of items like that filled with every symbol and it’s relative svg.

symbols: Symbol [
    {
        ...
        svg_uri: 'https://c2.scryfall.com/file/scryfall-symbols/card-symbols/W.svg'
        symbol: '{W}'
    },
    {
        ...
        svg_uri: 'https://c2.scryfall.com/file/scryfall-symbols/card-symbols/T.svg',
        symbol: '{T}'
        ...
    },
    {
        ...
        svg_uri: 'https://c2.scryfall.com/file/scryfall-symbols/card-symbols/B.svg',
        symbol: '{B}'
    }
    ...
]

My expected result from the previous string examples is:

<p>
    <div style="background-image: url('https://c2.scryfall.com/file/scryfall-symbols/card-symbols/W.svg" class="symbol"></div><div style="background-image: url('https://c2.scryfall.com/file/scryfall-symbols/card-symbols/B.svg" class="symbol"></div>, <div style="background-image: url('https://c2.scryfall.com/file/scryfall-symbols/card-symbols/T.svg" class="symbol"></div>: Prevent all combat damage that would be dealt by target creature this turn.
</p>

I want to find a way to:

  1. Parse the string
  2. Recognize one item between curly brackets
  3. Match that item with the symbol object (ImageSymbol)
  4. Create a tag with bg-image the uri of the matched symbol
  5. Replace the curly bracket and its content with the before mentioned div
  6. Make of the new string a p tag

My issue is that I don’t really know a way to parse the string to do such thing for strings that don’t have a fixed pattern.

As last reference I attach an example of another different card, with a different text from the one I have cited above:

Mtg-Card with symbol

Updates

I’ve found the solution of:

this._symbolService.symbology.data.forEach((item:  CardSymbol) => {
            const regEx = new RegExp(item.symbol, 'gm');
            const replacement = `<img src="${item.svg_uri}" class="card-symbol-image"/>`;
            this.oracleText = this.oracleText.replace(regEx, replacement);
          });

which is almost fine, but it breaks when the symbol string is ‘{0}’ or any other number. Is there any way to tell ts to match the exact string ‘{0}’ (or any other number)?

I hope that I can explain what I need.

Advertisement

Answer

{ has a special meaning in Regex, so it needs to be escaped with a backslash. This should do what you want:

this._symbolService.symbology.data.forEach((item:  CardSymbol) => {
            const regEx = new RegExp('\' + item.symbol, 'gm');
            const replacement = `<img src="${item.svg_uri}" class="card-symbol-image"/>`;
            this.oracleText = this.oracleText.replace(regEx, replacement);
          });
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement