#javascript #regex
#javascript #регулярное выражение
Вопрос:
Я понятия не имею, почему это зависает движок javascript, но это так. У кого-нибудь еще есть подсказка?
function isEnglish(text) {
const checker = /^(p{Emoji}|p{ASCII}) $/u;
return !!checker.exec(text.replace(/\n/g, ""));
}
text = `
RT @PROMOSIGROUP: FOLL TWITTER
3K:20rb
5k:30rb
10K:50rb
Foll IG aktif WW
100F:15rb
500F:50rb
1K:100rb
Jual Akun Twitter IG
081327927525/…`
isEnglish(text);
Хорошо, разобрался, символ «…» заставляет механизм регулярных выражений вращаться. Кто-нибудь знает, почему это может быть?
Комментарии:
1. В этом шаблоне есть обратное отслеживание, потому
p{ASCII}
что иp{Emoji}
оба совпадают с цифрами от 0 до 9 и#
и*
. Альтернативы не должны совпадать в одном и том же месте. Вы могли бы просто использовать символьный класс, хотя,/^[p{Emoji}p{ASCII}] $/u
Ответ №1:
Похоже, что ваш isEnglish()
тест должен возвращаться true
, когда исходный текст состоит исключительно из:
- US-символы ASCII,
- Эмодзи (не уверен, почему это будет считаться «английским», но неважно), и
- Пунктуация
и false
в противном случае.
Я мог бы указать, что US-ASCII охватывает от U 0000 до U 007F: это включает в себя управляющие символы C0 (от U 0000 до U 001F), а также [DEL] (U 007F), ни один из которых, за исключением пробелов, не является фактическим символом.
Но вы делаете гору из мухи слона: будет намного быстрее (и понятнее) просто искать первый символ, который не является частью вашего желаемого алфавита:
function isEnglish(s) {
return !rxIsNonEnglishAlphabet.test(s);
}
// -------------------------------------------------------
// this regular expression matches characters that are NOT
// * Whitespace
// * US-ASCII (u 0000 through U 007F)
// * Emoji
// * Punctuation
// -------------------------------------------------------
const rxIsNonEnglishAlphabet = /[^sp{ASCII}p{Emoji}p{Punctuation}]/u;
Комментарии:
1. Спасибо, это работает хорошо. Причина включения управляющих символов / смайликов / знаков препинания в юникоде заключается в том, что я фильтрую твиты и не хочу отбрасывать их только потому, что у них есть смайлик или перевод строки.
Ответ №2:
Оказывается, что мое регулярное выражение превращается в большую ошибку возврата, хотя для меня нет ничего очевидного, что могло бы вызвать это. Моя функция теперь выглядит совсем по-другому, чтобы заставить ее работать:
function isEnglish(text) {
const ascii = /p{ASCII}/ug;
const emoji = /p{Emoji}/ug;
const punct = /p{Punctuation}/ug;
text = text.replace(ascii, "");
text = text.replace(emoji, "");
text = text.replace(punct, "");
return text.length === 0;
}