mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-12-17 17:56:38 +00:00
feat: text censor (service updated to match censor patter instead of spliting input)
This commit is contained in:
parent
f7028f8683
commit
eff16d69a8
@ -4,46 +4,46 @@ export function censorText(input: string, options: InitialValuesType): string {
|
|||||||
if (!input) return '';
|
if (!input) return '';
|
||||||
if (!options.wordsToCensor) return input;
|
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)');
|
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
|
const wordsToCensor = options.wordsToCensor
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.map((word) => word.trim().toLowerCase())
|
.map((word) => word.trim())
|
||||||
.filter((word) => word.length > 0);
|
.filter((word) => word.length > 0);
|
||||||
|
|
||||||
const censoredText = textWords
|
let censoredText = input;
|
||||||
.map((word) => {
|
|
||||||
const lowerWord = word.toLowerCase();
|
for (const word of wordsToCensor) {
|
||||||
if (wordsToCensor.includes(lowerWord)) {
|
const escapedWord = escapeRegex(word);
|
||||||
if (options.censoredBySymbol) {
|
const pattern = new RegExp(`\\b${escapedWord}\\b`, 'giu');
|
||||||
return options.eachLetter
|
|
||||||
? options.censorSymbol.repeat(word.length)
|
const replacement = options.censoredBySymbol
|
||||||
: options.censorSymbol;
|
? options.eachLetter
|
||||||
} else {
|
? options.censorSymbol.repeat(word.length)
|
||||||
return options.censorWord;
|
: options.censorSymbol
|
||||||
}
|
: options.censorWord;
|
||||||
}
|
|
||||||
return word;
|
censoredText = censoredText.replace(pattern, replacement);
|
||||||
})
|
}
|
||||||
.join('');
|
|
||||||
|
|
||||||
return censoredText;
|
return censoredText;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a character is a symbol or emoji.
|
* Escapes RegExp special characters in a string
|
||||||
* Accepts single characters that are non-letter and non-number,
|
*/
|
||||||
* or extended pictographic characters (like emojis).
|
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 {
|
function isSymbol(input: string): boolean {
|
||||||
return (
|
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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user