简体   繁体   中英

JavaScript match whole string user selected, skip email and URL

I tried to using regular expression to match whole string (user selected, could be ONE word or MULTIPLE words) from a paragraph.

var str = 'myname this is my myname 18 my email is MyName@email.com 40 another email is support@MYNAME.com.au. 78 and my site is www.myname.com.au. 119 myname. 142 ..myname 154 [myname] 167 and myname\'s 184 mynamebefore 198 aftermynames 215 "myname" 231 \'myname\' 244 lastmyname';

function match(text, str) {
     //need to change
    var pattern = '(?=^|\\s|\\b)(' + text + ')(?=$|\\s|\\b)';

    var regexp = new RegExp(pattern, "ig"); 
        var idx = 0;
        while ((match = regexp.exec(str)) != null) {   
            var offsetStart = parseInt(match.index);
            console.log("--["+idx+"] ["+offsetStart+"]- textnode  " + JSON.stringify(match, null, '    '));
            idx++;

        }
}


var selectText = 'myname';
match(selectText, str);

What I want is that see the string below has been highlight in the string.

' myname this is my myname 18 my email is MyName@email.com 40 another email is support@MYNAME.com.au. 78 and my site is www.myname.com.au. 119 myname . 142 .. myname 154 [ myname ] 167 and myname \\'s 184 mynamebefore 198 aftermynames 215 " myname " 231 \\' myname \\' 244 lastmyname'

Skip email, skip URL, return the string has been matched which can be wrapped by space or any other characters [^a-zA-Z0-9] like [], '', "" or 's.

All text is bold like myname will return.

First match the string using regexp "[^@.]"+text+"[^@.]"

Then each item as shown in the code forEach .

Then return the string.

Check the snippet

 var str = 'myname this is my myname 18 my email is MyName@email.com 40 another email is support@MYNAME.com.au. 78 and my site is www.myname.com.au. 119 myname. 142 ..myname 154 [myname] 167 and myname\\'s 184 mynamebefore 198 aftermynames 215 "myname" 231 \\'myname\\' 244 myname'; function match(text, str) { var re=new RegExp("([^@a-zA-Z0-9]|^)"+text+"(\\.\\s|[^@a-zA-Z0-9.])","igm"); str.match(re).forEach(function(i,p){ str=str.replace(i,"<b>"+i+"</b>"); }); return str; } var selectText = 'myname'; document.writeln("Before<br /><br />"+str); document.write("<br /><br />After<br /><br />"+match(selectText, str)); 

You could use a split-join to first separate potential candidates but this requires to capture exceptions like when . is used in a website, so the idea is to first exclude . as a split char, but then for each item check if it should be included base on other rules (eg if split further by . contains name but not www ).

For example:

const text = 'myname this is my myname ...';

const name = 'myname';

// used to check if a found value is indeed ok, excludes e.g. www. texts but keeps things like '..name'; can be customized and improved to better fit the case
const check = val => val === name || 
    (val.split(/\./).some(_ => _ === name) && !val.split(/\./).some(_ => _ === 'www')) ;

const res = text
    .split(/([^a-zA-Z0-9\.])/)
    .map(val => check(val) ? `<b>${val}</b>` : val)
    .join('');

This works in your current scenario and might be good enough.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM