2

I want to match string with or without comma and space:

<div>
"hello world"
<br>
"hello,world"
<br>
"hello world,"
<br>
",hello world"
<br>
",hello,world,"
<br>
", hello , world ,"
</div>

so if i search for example "world" i want to find it with or without comma and space and highlight the result

 var search = "world";
 //or
 var search = "world,";
 //or
 var search = ",world";
 //or
 var search = ",world,";
 div.replace(new RegExp('(' + search + ')', 'gi'), '<span class="highlighted">$1</span>')

like this:

<div>
    "hello <span class="highlighted">world</span>"
    <br>
    "hello<span class="highlighted">,world</span>"
    <br>
    "hello <span class="highlighted">world,</span>"
    <br>
    ",hello <span class="highlighted">world</span>"
    <br>
    ",hello<span class="highlighted">,world,</span>"
    <br>
    ", hello <span class="highlighted">, world ,</span>"

here an example of what i want : https://jsfiddle.net/nvdhqf23/5/

i solved it thanks to TMKelleher https://jsfiddle.net/nvdhqf23/6/

jsem
  • 181
  • 2
  • 12
  • 1
    Also try this regex `(?:,\s*)?world(?:\s*,)?` [check demo](https://regex101.com/r/tO7gB5/1). – bobble bubble Nov 08 '15 at 18:12
  • thanks this works for one world what about if i search for "hello world" how to to match "hello,world" and ", hello , world ," – jsem Nov 08 '15 at 18:41

3 Answers3

4
/([\s,]\s*world\s*,?)/i

[\s,] let's us either have a space or a comma to ensure there is a separation between the words. Then following it with \s* allows for zero to many white spaces between the comma/space and the word world. We then follow that up with some more \s* before the ,? which means one or none commas. Then we capture () it with a case insensitive, i, regular expression.


This should handle the replacing.

<style>
.highlighted {
   background-color: rgb(100,100,255);
   color: white;
}
</style>

<div id = "0">
"hello world"
<br>
"hello,world"
<br>
"hello world,"
<br>
",hello world"
<br>
",hello,world,"
<br>
", hello , world ,"
</div>
<div id="1"></div>

<script>
var content = document.getElementById("0").innerHTML.split("<br>"),
    result  = [];
for(var i in content) {
    // First extract what we want.
    var world = /([\s,]\s*world\s*,?)/.exec(content[i])[1],
    // Split everything up to make the insertion easier.
    hello     = content[i].split(world);
    // Place the result back.
    result.push(hello.join('<span class="highlighted">'+world+'</span>'));
}
document.getElementById("1").innerHTML = result.join("<br>");
</script>

UPDATE To fit what @jsem asked down in the comments, I created a function that will determine the correct phrase, such as "hello world" or the many others based off of the search and punctuation.

function separate(search, punc) {
   if(typeof punc !== "string") punc = ",";
   var phrase = new RegExp(".*?(\\w+)\\s*(?:"+punc+"|\\s)\\s*(\\w+)\\s*(?:"+punc+")?","i").exec(search);
   if(!phrase) throw new Error("Search passed could not be parsed.");
   return {word1:phrase[1], word2:phrase[2]};
};

Then used the information gathered from that to create a unique regular expression that will grab the information to be highlighted.

function build_regex(phrase, punc) {
    if(typeof punc !== "string") punc = ",";
    return new RegExp("^.*?"+phrase.word1+"\\s*((?:"+punc+"|\\s)\\s*"+phrase.word2+"\\s*(?:"+punc+")?).*$", "i");
};

With these two functions, I created a highlighting function using the same splitting and joining algorithm as before.

function highlight(sentence, search, punc) {
    if(typeof punc !== "string") punc = ",";
    var highlighted = build_regex(separate(search, punc), punc).exec(sentence)[1],
        remains     = sentence.split(highlighted);
    return remains.join('<span class="highlighted">'+highlighted+'</span>');
};

Ex:

highlight("This is my sentence hello, world!", "hello world");
/* Output: This is my sentence hello<span class="highlighted">, world</span>!*/
highlight("Change things up... sir.", "up sir", "\\.\\.\\.");
/* Output: Change things up<span class="highlighted">... sir</span>.*/
highlight("Give me some options? ummm...", "options! ummm", "\\?|\\!");
/* Output: Give me some options<span class="highlighted">? ummm</span>...*/
tkellehe
  • 659
  • 5
  • 11
  • ok thank you but one more thing if i want to match "hello word" and using the first ^ and last $ regex how to do it? – jsem Nov 08 '15 at 19:48
  • `^.*` Start from beginning grabbing everything up to what we want. `.*$` Start from ending grabbing everything. `^.*([\s,]\s*world\s*,?).*$` Not sure if that is what you meant? – tkellehe Nov 08 '15 at 19:56
  • i mean i want also to find when i search for "hello world" to match also "hello,world" or " hellow, world " or" hellow ,world " or ",hellow world" or "helow world," using first and last ^ $ expression with or without space .. – jsem Nov 08 '15 at 20:07
  • Here is a a more generic of what I think you mean: `^.*?(\w+\s*[\s,]\s*\w+\s*,?).*$` The `^.*?` will grab from the beginning to the first recognized pattern non-greedy (will not grab `hello`). The `\w+` means at least one word character (for JavaScript that is `[a-zA-Z0-9_]`). To see it for your "hello world" - `^.*?(hello\s*[\s,]\s*world\s*,?).*$`. Is that what you wanted? – tkellehe Nov 08 '15 at 23:11
  • see this example of my improved text highlighter https://jsfiddle.net/nvdhqf23/5/ able to highlight Arabic and english and french diacritic when i enter for "hello world" i want to match text that have symbols or Punctuation too like "hello , world" – jsem Nov 08 '15 at 23:59
  • Does that help some? – tkellehe Nov 09 '15 at 01:59
1

Try this for your regex:

var re = /([,|\s]+)?world([,|\s]+)?/g; 
acupofjose
  • 2,159
  • 1
  • 22
  • 40
0

Just add an ? optional sign right after the commas in your search variable:

var search = ",?world,?";

And, if you really want to match spaces (to hilight?!), just add \s*, which means from zero to many spaces:

div.replace(new RegExp('(\\s*' + search + '\\s*)', 'gi'), ...

Hope it helps.