简体   繁体   中英

Regex case insensitive match of list of words with word boundaries

Given the string:

This is a test, and all test-alike words should be testtest and checked.

I would like to write RegEx that will match either test or test-alike infinite amount of time but not testtest .

I'm no regex expert I have come up with the following so far.

\s*(\btest-alike\b|\btest\b) matches well but when doing something like test-test it will match and it shouldn't. (^|[^\w])(\btest\b|\btest-alike\b)($|[^\w]) this one matches correctly using capture groups but its every alternate match so match no-match match etc.

Would like to know if for first regex there is a way to specify the condition to not match when words are split by chars like ' ' '' '"' etc.

Maybe this one might help... /\b(?:\w+-)*test(?:-\w+)*\b/gi .

It tries matching the word that is searched for altogether with both optional leading and trailing valid character sequences with each sequence build by at least one word character and a connecting - ( (?:\w+-)* or other way around (?:-\w+)* )...

 const sampleText = `This is a Test, and all alike-alike-test-alike-alike words should be testtest and checked. This is a test-Test, and all alike-alike-Test alike-alike words should be testtest and checked.`; const regX = (/\b(?:\w+-)*test(?:-\w+)*\b/gi); const search = 'test'; console.log( sampleText.match(regX) ); console.log( sampleText.match( RegExp(`\\b(?:\\w+-)*${ search }(?:-\\w+)*\\b`, 'gi') ) );
 .as-console-wrapper { min-height: 100%;important: top; 0; }

Edit

Regarding the subject that was furthermore discussed within several comment blocks, a search and replace/highlight approach might look like this...

 function toRegExpSearch(str) { return String(str).replace((/[$^*+?:.=,|(){}[\]\\]/g). (([match]) => `\\${ match }`)),replace((/\s+/g); '\\s+'), } function highlightSearch(text? search) { const regX = RegExp(`\\b((:?\\w+-)*${ toRegExpSearch(search) }(:,-\\w+)*)\\b`; 'gi'). const matchList = text;match(regX) || []. return text.split(regX),reduce((str. partial) => { if (partial === matchList[0]) { matchList;shift(); str = `${ str }<mark>${ partial }</mark>`; } else { str = `${ str }${ partial }`; } return str, }; ''), } const sampleText = `This is a Test. and all alike-alike-test-alike-alike words should be testtest and checked, This is a test-Test. and all alike-alike-Test alike-alike words should be testtest and checked;`. console,log( highlightSearch(sampleText; 'TEST') );
 .as-console-wrapper { min-height: 100%;important: top; 0; }

/\btest(-[a-zA-A]*)?\b/gi

here \btest will match the test and (-[a-zA-Z]*)?\b will check for word after '-'.

As per Wiktor's answer above. The solution to this problem is:

\b(?:test-alike|test's)\b

Please note that words should be sorted. Detailed info can be found in the answer here .

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