Пробелы Dart RegExp не распознаются
Я пытаюсь реализовать шаблон регулярного выражения для имени пользователя, который допускает английские буквы, арабские буквы, цифры, тире и пробел.
Следующий шаблон всегда не возвращает совпадений, если во входной строке есть пробел, даже если \ s включен в шаблон.
Pattern _usernamePattern = r'^[a-zA-Z0-9\u0621-\u064A\-\s]{3,30}$';
Я также попытался заменить \ s на "" и \\ s, но регулярное выражение всегда не возвращает совпадений для любого ввода, в котором есть пробел.
Изменить: оказывается, что флаттер добавляет символ Юникода для «Знака справа налево» или «Знака слева направо» при использовании текстового поля со смесью языков, которые идут LTR или RTL. Этот дополнительный знак представляет собой символ Юникода, который добавляется к тексту. Регулярное выражение выше не работало из-за этого дополнительного символа. Чтобы решить эту проблему, просто выполните replaceAll для этих символов. Подробнее здесь:https://github.com/flutter/flutter/issues/56514.
Ответы
Это довольно неприятная проблема, и ее стоит задокументировать здесь.
Как указано в источнике :
/// When LTR text is entered into an RTL field, or RTL text is entered into an
/// LTR field, [LRM](https://en.wikipedia.org/wiki/Left-to-right_mark) or
/// [RLM](https://en.wikipedia.org/wiki/Right-to-left_mark) characters will be
/// inserted alongside whitespace characters, respectively. This is to
/// eliminate ambiguous directionality in whitespace and ensure proper caret
/// placement. These characters will affect the length of the string and may
/// need to be parsed out when doing things like string comparison with other
/// text.
Хотя это сделано с благими намерениями, это может вызвать проблемы при работе со смешанными текстовыми шаблонами LTR / RTL (как в данном случае) и при необходимости обеспечения точной длины поля и т. Д.
Предложил решение удалить все лево-право-метки :
void main() {
final String lrm = 'aaaa \u{200e}bbbb';
print('lrm: "$lrm" with length ${lrm.length}');
final String lrmFree = lrm.replaceAll(RegExp(r'\u{200e}', unicode: true), '');
print('lrmFree: "$lrmFree" with length ${lrmFree.length}');
}
Связано: справа налево (RTL) во флаттере