/**
* splitWords
*
* Splits free text into words using a Unicode-aware regex.
*
* JavaScript does NOT support \p{L} or \P{L} in standard regex.
* But it DOES support Unicode property escapes with the "u" flag:
*
* \p{Letter} → any Unicode letter
*
* So we split on ANY sequence of NON-letters:
*
* /[^\p{Letter}]+/u
*
* This is fully Unicode-aware and works in modern JS engines.
*/
function splitWords(text) {
text = text.trim();
// Split on any sequence of non-letter characters
return text.split(/[^\p{Letter}]+/u);
}
/**
* removeDuplicateWords
*
* Removes duplicate words while preserving:
* - original order
* - original casing of first occurrence
* - case-insensitive comparison
*
* Uses Set for O(1) average lookup time.
*/
function removeDuplicateWords(text) {
const words = splitWords(text);
const seen = new Set();
const unique = [];
for (const word of words) {
if (word === "") continue;
const key = word.toLowerCase(); // Unicode-aware lowercase
if (!seen.has(key)) {
seen.add(key);
unique.push(word); // preserve original casing
}
}
// Reassemble into a space-separated string
return unique.join(" ");
}
// ------------------------------------------------------------
// Program entry point
// ------------------------------------------------------------
const input =
"Hello, hello! This is a test. A TEST, hello universe... " +
"UNIVERSE! Hello; *** Is Anybody There?";
const output = removeDuplicateWords(input);
console.log(output);
/*
run:
Hello This is a test universe Anybody There
*/