mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-09-18 05:29:33 +02:00
feat: text censor (service updated to match censor patter instead of spliting input)
This commit is contained in:
@@ -4,46 +4,46 @@ export function censorText(input: string, options: InitialValuesType): string {
|
||||
if (!input) return '';
|
||||
if (!options.wordsToCensor) return input;
|
||||
|
||||
if (options.censoredBySymbol && !isSymbol(options.censorSymbol[0])) {
|
||||
if (options.censoredBySymbol && !isSymbol(options.censorSymbol)) {
|
||||
throw new Error('Enter a valid censor symbol (non-alphanumeric or emoji)');
|
||||
}
|
||||
|
||||
// Split text into words and punctuation using Unicode-aware regex
|
||||
const regex = /([\s\p{P}])/gu;
|
||||
const textWords = input.split(regex);
|
||||
|
||||
// Normalize censor words (trim and lowercase)
|
||||
const wordsToCensor = options.wordsToCensor
|
||||
.split('\n')
|
||||
.map((word) => word.trim().toLowerCase())
|
||||
.map((word) => word.trim())
|
||||
.filter((word) => word.length > 0);
|
||||
|
||||
const censoredText = textWords
|
||||
.map((word) => {
|
||||
const lowerWord = word.toLowerCase();
|
||||
if (wordsToCensor.includes(lowerWord)) {
|
||||
if (options.censoredBySymbol) {
|
||||
return options.eachLetter
|
||||
? options.censorSymbol.repeat(word.length)
|
||||
: options.censorSymbol;
|
||||
} else {
|
||||
return options.censorWord;
|
||||
}
|
||||
}
|
||||
return word;
|
||||
})
|
||||
.join('');
|
||||
let censoredText = input;
|
||||
|
||||
for (const word of wordsToCensor) {
|
||||
const escapedWord = escapeRegex(word);
|
||||
const pattern = new RegExp(`\\b${escapedWord}\\b`, 'giu');
|
||||
|
||||
const replacement = options.censoredBySymbol
|
||||
? options.eachLetter
|
||||
? options.censorSymbol.repeat(word.length)
|
||||
: options.censorSymbol
|
||||
: options.censorWord;
|
||||
|
||||
censoredText = censoredText.replace(pattern, replacement);
|
||||
}
|
||||
|
||||
return censoredText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a character is a symbol or emoji.
|
||||
* Accepts single characters that are non-letter and non-number,
|
||||
* or extended pictographic characters (like emojis).
|
||||
* Escapes RegExp special characters in a string
|
||||
*/
|
||||
function escapeRegex(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a string is a valid symbol or emoji (multi-codepoint supported).
|
||||
*/
|
||||
function isSymbol(input: string): boolean {
|
||||
return (
|
||||
/^[^\p{L}\p{N}]+$/u.test(input) || /\p{Extended_Pictographic}/u.test(input)
|
||||
/^[^\p{L}\p{N}]+$/u.test(input) || // Not a letter or number
|
||||
/\p{Extended_Pictographic}/u.test(input) // Emoji or pictographic symbol
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user