0

I need to search a string, and if it has any values that match my array, I need to add <span></span> tags to them to add custom CSS. I am using reactJS.

  1. How do I search the string for objects from my array? Example:

    let string = 'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input1}}' let array = [{parameter: '{{input1}}'},{parameter: '{{input2}}'},...] findAllOccurrances = () => {???}

  2. Then systematically replace them '{{inputX}}' with <span className='bizarre-highlight'>{{inputX}}</span>

My intent is to add custom CSS to any text in the div which matches my array, so if you got any ideas please shoot! Again, using reactJS if that helps.

3 Answers 3

1

I created a component that will replace the elements that need to be highlighted with a span you can test it here

The component is:

import React from 'react';

export default ({ terms, children }) => {
  const result = []
  const regex = terms.map(escapeRegExp).join('|');
  const re = new RegExp(regex);
  let text = (' ' + children).slice(1); // copy
  let match = re.exec(text);
  while (match != null) {
    const str = match.toString();
    result.push(text.slice(0, match.index));
    result.push(<span className="highlighted">{str}</span>);
    text = text.slice(match.index + str.length);
    match = re.exec(text);
  }
  result.push(text);
  return result;
}

function escapeRegExp (str) {
  return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
}

And you should use it like this:

import React from 'react';
import Highlighter from './Highlighter';

const terms = [ '{{input1}}', '{{input2}}' ]

const App = () => (
  <div>
    <Highlighter terms={terms}>
      {'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input1}}'}
    </Highlighter>
  </div>
);
Sign up to request clarification or add additional context in comments.

5 Comments

I will need check it out, but the link to it working was completely accurate! thank you!!!!
@KevinDanikowski If you need anything just ask, I'll be happy to help.
Hey @kakamg0, I keep receiving 'Warning: Each child in an array or iterator should have a unique "key" prop.' due to adding the code if (allParametersQuery.allParameters && (!allParametersQuery.allParameters.loading && !allParametersQuery.allParameters.error)) terms= allParametersQuery.allParameters.map((parameter) => {return '{{' + parameter.param + '}}'}) , I set allParametersQuery to be what I passed to this component through terms. Any idea why this map is causing this issue?
I think the warning is coming from the result array in the Highlighter component, you should change result.push(<span className="highlighted">{str}</span>); to result.push(<span key={match.index} className="highlighted">{str}</span>);. You can read more about the warning here
you're a genius thank you! match.index gave duplicate keys, I used message.length. Works well enough without giving errors.
1

Use String#replace with a RegExp to find all instances of '{{inputX}}', and wrap the matches with the span:

const string = 'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input3}}'

const array = [{parameter: '{{input1}}'},{parameter: '{{input2}}'}]

const pattern = new RegExp(array.map(({ parameter }) => parameter).join('|'), 'g');

const result = string.replace(pattern, (match) => 
  `<span className='bizarre-highlight'>${match}</span>`
)

console.log(result)

Comments

1

use Array#map to extract values for wrapping in <span> and then cycle on them for replacement:

let string = 'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input1}}';
let array = [{parameter: '{{input1}}'},{parameter: '{{input2}}'}];

array.map(el => { return el.parameter }).forEach(str => {
  string = string.split(str).join("<span className=\'bizarre-highlight\'>" + str + "</span>");
});
    
console.log(string);

3 Comments

This worked and replaced what I needed. Thank you! it didn't solve my issue of adding CSS to the text, but I should be on the right path now.
@KevinDanikowski why not add style attribute to span?
to be honest I don't know how that would change it or what exactly you mean. Right now I'm trying to figure a way to get the spans out of the string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.