3

I have a text with \n characters inside and I have an array of phrases I want to highlight in this text by wrapping its segments with tag. The problem is that I can't find this phrases in text if there is a \n symbol.

I've tried to replace \n from text, but I need to restore them after highlight.

let text = 'Looking For An Enterprise Test Authoring Platform?\n
Learn More About Gauge\n
Watch our video to learn if Gauge can help you.'

let phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"]

const highlight = (phrase) => text.replace(phrase, `<mark style="background: #4CAF50">${phrase}</mark>`)

phrases.map(phrase=> text = highlight(phrase))

Only last phrase will match with text. I'm looking for some way to ignore \n and match all this phrases. Or maybe there is another way to solve this. I would appreciate any help!

m02ph3u5
  • 3,022
  • 7
  • 38
  • 51
  • If line breaks can only occur _between_ the words, then you could rather easily write your search patterns as actual regular expressions that allow for line breaks between them. Combine that with capturing the match, so you can use it for the replacement afterwards. – misorude Aug 07 '19 at 12:13
  • (But what you have won’t work for multiple, _overlapping_ replacements to begin with - if you ever had `mark` or `style` as “phrases” to replace, that would of course mess up any previous replacements you have already done.) – misorude Aug 07 '19 at 12:15

3 Answers3

1

One option is to loop through the phrase and create a dynamci regex. Replace every \s with (?:\n)*. This will create a dynamic regex like this:

/Authoring(?:\n)* Platform\?(?:\n)* Learn(?:\n)* More/

Then replace the text with matched substring using $&. This will preserve the \n from the original string.

let text = 'Looking For An Enterprise Test Authoring Platform?\n Learn More About Gauge\n Watch our video to learn if Gauge can help you.'

let phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"]

// https://stackoverflow.com/a/494122
const escape = str => str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1")

phrases.forEach(p => {
  const regex = new RegExp( escape(p).replace(/\s/g, '\(?:\n)* ') )
  text = text.replace(regex, `<mark style="background:#4CAF50">$&</mark>`)
})

console.log(text)

The escape function is taken from here. It is used to escape metacharacters like ? from each phrase

Here's an alternative using reduce and some helper functions:

const text = 'Looking For An Enterprise Test Authoring Platform?\n Learn More About Gauge\n Watch our video to learn if Gauge can help you.',
      phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"],
      escape = str => str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"),
      createReg = p => new RegExp( escape(p).replace(/\s/g, '\(?:\n)* ') ),
      replaceWith = '<mark style="background:#4CAF50">$&</mark>',
      output = phrases.reduce((a, p) => a.replace(createReg(p), replaceWith), text)

console.log(output)
adiga
  • 34,372
  • 9
  • 61
  • 83
0

You can potentially go around by taking the first word and matching your sentence with this simple regex \bfirstWord (.*?) endWord\b

let text = 'Looking For An Enterprise Test Authoring Platform?\n
            Learn More About Gauge\n
            Watch our video to learn ifGauge can help you.';

 text.match(/\Gauge (.*?) video\b/gis)
 // ["Gauge↵↵Watch our video"]
 // \n character is being preserved

It will probably make it a little more complicate though because you need to find the first and the last word of each sentence.

NickHTTPS
  • 744
  • 4
  • 16
-1

Just remove the \n from the string and check for phrases in that string like this.

let text = 'Looking For An Enterprise Test Authoring Platform?\n
Learn More About Gauge\n
Watch our video to learn ifGauge can help you.';

let phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"];

//string without \n
let plainText = text.replace("\n", "");

const highlight = (phrase) => {
    return plainText.replace(phrase, `<mark style="background: #4CAF50">${phrase}</mark>`)
}


phrases.map(phrase=> {
    text = highlight(phrase)
})  
Swapnil Shukla
  • 229
  • 1
  • 8
  • 2
    "*I've tried to replace \n from text, but **I need to restore them after highlight**.*" – David Thomas Aug 07 '19 at 12:06
  • Lazy solution: First save the index (positions) of \n -> remove them from string -> Replace the substring -> Re-add \n to the string at positions stored in first step – Adams Hales Aug 07 '19 at 12:16
  • 1
    @AdamsHales the position of where `\n` needs to go would change after surrounding the phrase –  Aug 07 '19 at 12:19