Gli spazi bianchi Dart RegExp non vengono riconosciuti

Aug 19 2020

Sto cercando di implementare un pattern regex per il nome utente che consente lettere inglesi, arabe, cifre, trattini e spazi.

Il modello seguente non restituisce sempre alcuna corrispondenza se la stringa di input ha uno spazio anche se \ s è incluso nel modello

Pattern _usernamePattern = r'^[a-zA-Z0-9\u0621-\u064A\-\s]{3,30}$';

Ho anche provato a sostituire \ s con "" e \\ s, ma la regex non restituisce sempre corrispondenze per qualsiasi input contenente uno spazio.

Modifica: si scopre che flutter aggiunge un carattere Unicode per "Segno da destra a sinistra" o "Segno da sinistra a destra" quando si utilizza un campo di testo con un mix di lingue che vanno LTR o RTL. Questo segno aggiuntivo è un carattere Unicode che viene aggiunto al testo. L'espressione regolare precedente non funzionava a causa di questo carattere aggiuntivo. Per risolvere il problema, eseguire semplicemente una sostituzione di tutti questi caratteri. Leggi di più qui:https://github.com/flutter/flutter/issues/56514.

Risposte

2 wp78de Aug 20 2020 at 03:34

Questo è un problema abbastanza brutto e vale la pena documentarlo in una risposta qui.

Come documentato nella fonte :

  /// 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.

Sebbene ciò sia ben inteso, può causare problemi quando si lavora con schemi di testo LTR / RTL misti (come nel caso qui) e si deve garantire la lunghezza esatta del campo, ecc.

La soluzione suggerita è rimuovere tutti i segni sinistra-destra :

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}');
}

Correlati: da destra a sinistra (RTL) in flutter