Reputation: 75
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 [email protected] 40 another email is [email protected]. 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 [email protected] 40 another email is [email protected]. 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.
Upvotes: 0
Views: 86
Reputation: 5413
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 (e.g. 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.
Upvotes: 0
Reputation: 12478
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 [email protected] 40 another email is [email protected]. 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));
Upvotes: 1