Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

String.replace but returning fragments

Here is something that I’d like to achieve:


const symbolRegex = /[a-zA-Z_$][a-zA-Z_$0-9]*/g;

export function CodeSymbol(props: {code: string; symbols: SymbolMap}) {
  return (
    <code>
      {props.code.replace(symbolRegex, (symbol): any => {
        const packageName = props.symbols.get(symbol);
        if (packageName) {
          return <a href={`/api/${packageName}/${symbol}`}>{symbol}</a>;
        }
        return <>{symbol}</>;
      })}
    </code>
  );
}

Where SymbolMap is basically a Map<string, string>.

Of course this doesn’t work because, the preact fragment is converted to string and I get something like: Observable<[object Object]<any>> from the Observable<HttpEvent<any>> input (HttpEvent is defined in the map, but Observable isn’t) .

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What would you suggest?

>Solution :

Here’s one way to achieve this by using .split + .map with a regex that has one single capturing group that captures the whole matching part. With a regex like that, every even index in the array will be a non matching substring and every odd one will be a matching substring.

import { render } from 'preact';

const symbolRegex = /([a-zA-Z_$][a-zA-Z_$0-9]*)/;

function CodeSymbol(props: {code: string; symbols: SymbolMap}) {
  return (
    <code>
      {props.code.split(symbolRegex).map((symbol, index) => {
        // Every even index is a non-match when the regex has 1 capturing group
        if (index % 2 === 0) return symbol;
        const packageName = props.symbols.get(symbol);
        if (packageName) {
          return <a href={`/api/${packageName}/${symbol}`}>{symbol}</a>;
        }
        return symbol;
      })}
    </code>
  );
}


render(<CodeSymbol code="foo bar" symbols={new Map([["foo", "foopackage"]])} />, document.getElementById('app'));

REPL

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading