mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
111 lines
4.3 KiB
TypeScript
111 lines
4.3 KiB
TypeScript
import { Comment } from '@plebbit/plebbit-react-hooks';
|
|
|
|
/**
|
|
* Checks if a text matches a pattern according to various pattern matching rules:
|
|
* - Whole word matching: 'feel' matches 'feel' but not 'feeling'
|
|
* - AND operator: 'feel girlfriend' matches both words in any order
|
|
* - OR operator: 'feel|girlfriend' matches either word
|
|
* - Mixed operators: 'girlfriend|boyfriend feel' matches complex logic
|
|
* - Exact match: "that feel when" matches the exact phrase
|
|
* - Wildcards: 'feel*' matches 'feel', 'feels', 'feeling', etc.
|
|
* - Regex: /pattern/flags for regular expressions
|
|
*
|
|
* @param text The text to check against the pattern
|
|
* @param pattern The pattern to match
|
|
* @returns True if the text matches the pattern, false otherwise
|
|
*/
|
|
export const matchesPattern = (text: string, pattern: string): boolean => {
|
|
if (!pattern || !text) return false;
|
|
|
|
const textLower = text.toLowerCase();
|
|
|
|
try {
|
|
// Check if it's a regex pattern (starts and ends with /)
|
|
if (pattern.startsWith('/') && pattern.length > 2 && /\/[gimsuy]*$/.test(pattern)) {
|
|
const lastSlashIndex = pattern.lastIndexOf('/');
|
|
const regexPattern = pattern.substring(1, lastSlashIndex);
|
|
const flags = pattern.substring(lastSlashIndex + 1);
|
|
const regex = new RegExp(regexPattern, flags);
|
|
return regex.test(textLower);
|
|
}
|
|
// Check if it's an exact match pattern (surrounded by quotes)
|
|
else if (pattern.startsWith('"') && pattern.endsWith('"') && pattern.length > 2) {
|
|
const exactPattern = pattern.substring(1, pattern.length - 1).toLowerCase();
|
|
return textLower.includes(exactPattern);
|
|
}
|
|
// Check for OR patterns (contains |)
|
|
else if (pattern.includes('|')) {
|
|
const orGroups = pattern.split(' ').filter(Boolean);
|
|
|
|
// Process each group (which might contain OR operators)
|
|
return orGroups.every((group) => {
|
|
const orTerms = group.split('|').map((term) => term.toLowerCase());
|
|
return orTerms.some((term) => {
|
|
// Handle wildcards in OR terms
|
|
if (term.includes('*')) {
|
|
const regexPattern = term.replace(/\*/g, '.*').toLowerCase();
|
|
const regex = new RegExp(`\\b${regexPattern}\\b`, 'i');
|
|
return regex.test(textLower);
|
|
} else {
|
|
// Match whole word only
|
|
const regex = new RegExp(`\\b${term}\\b`, 'i');
|
|
return regex.test(textLower);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
// Check for AND patterns (space-separated words)
|
|
else if (pattern.includes(' ')) {
|
|
const andTerms = pattern
|
|
.split(' ')
|
|
.filter(Boolean)
|
|
.map((term) => term.toLowerCase());
|
|
return andTerms.every((term) => {
|
|
// Handle wildcards in AND terms
|
|
if (term.includes('*')) {
|
|
const regexPattern = term.replace(/\*/g, '.*').toLowerCase();
|
|
const regex = new RegExp(`\\b${regexPattern}\\b`, 'i');
|
|
return regex.test(textLower);
|
|
} else {
|
|
// Match whole word only
|
|
const regex = new RegExp(`\\b${term}\\b`, 'i');
|
|
return regex.test(textLower);
|
|
}
|
|
});
|
|
}
|
|
// Handle wildcard patterns
|
|
else if (pattern.includes('*')) {
|
|
const regexPattern = pattern.replace(/\*/g, '.*').toLowerCase();
|
|
const regex = new RegExp(`\\b${regexPattern}\\b`, 'i');
|
|
return regex.test(textLower);
|
|
}
|
|
// Simple whole word match
|
|
else {
|
|
const regex = new RegExp(`\\b${pattern.toLowerCase()}\\b`, 'i');
|
|
return regex.test(textLower);
|
|
}
|
|
} catch (error) {
|
|
// If regex parsing fails, fall back to simple includes
|
|
console.error('Pattern matching error:', error);
|
|
const simplifiedPattern = pattern.toLowerCase();
|
|
return textLower.includes(simplifiedPattern);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Checks if a comment matches a pattern in its title or content
|
|
*
|
|
* @param comment The comment to check
|
|
* @param pattern The pattern to match
|
|
* @returns True if the comment matches the pattern, false otherwise
|
|
*/
|
|
export const commentMatchesPattern = (comment: Comment, pattern: string): boolean => {
|
|
if (!pattern || !comment) return false;
|
|
|
|
const titleLower = comment?.title?.toLowerCase() || '';
|
|
const contentLower = comment?.content?.toLowerCase() || '';
|
|
const textToMatch = titleLower + ' ' + contentLower;
|
|
|
|
return matchesPattern(textToMatch, pattern);
|
|
};
|