Les espaces blancs Dart RegExp ne sont pas reconnus
J'essaie d'implémenter un modèle d'expression régulière pour le nom d'utilisateur qui autorise les lettres anglaises, les lettres arabes, les chiffres, le tiret et l'espace.
Le modèle suivant ne renvoie toujours aucune correspondance si la chaîne d'entrée a un espace même si \ s est inclus dans le modèle
Pattern _usernamePattern = r'^[a-zA-Z0-9\u0621-\u064A\-\s]{3,30}$';
J'ai également essayé de remplacer \ s par "" et \\ s, mais l'expression régulière ne renvoie toujours aucune correspondance pour toute entrée contenant un espace.
Edit: Il s'avère que le flutter ajoute un caractère unicode pour "Marque de droite à gauche" ou "Marque de gauche à droite" lors de l'utilisation d'un champ de texte avec un mélange de langues qui vont LTR ou RTL. Cette marque supplémentaire est un caractère Unicode qui est ajouté au texte. L'expression régulière ci-dessus échouait à cause de ce caractère supplémentaire. Pour résoudre le problème, effectuez simplement un replaceAll pour ces caractères. En savoir plus ici:https://github.com/flutter/flutter/issues/56514.
Réponses
C'est un problème assez désagréable et mérite d'être documenté dans une réponse ici.
Comme documenté dans la source :
/// 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.
Bien que cela soit bien intentionné, cela peut poser des problèmes lorsque vous travaillez avec des modèles de texte mixtes LTR / RTL (comme c'est le cas ici) et que vous devez garantir une longueur de champ exacte, etc.
La solution suggérée est de supprimer toutes les marques gauche-droite :
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}');
}
Connexes: de droite à gauche (RTL) en scintillement