Dart RegExp 공백이 인식되지 않습니다.

Aug 19 2020

영어 문자, 아랍어 문자, 숫자, 대시 및 공백을 허용하는 사용자 이름에 대한 정규식 패턴을 구현하려고합니다.

다음 패턴은 패턴에 \ s가 포함되어 있어도 입력 문자열에 공백이 있으면 항상 일치하는 항목이 없습니다.

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

또한 \ s를 ""및 \\ s로 바꾸려고 시도했지만 정규식은 항상 공백이있는 입력에 대해 일치하는 항목을 반환하지 않습니다.

편집 : LTR 또는 RTL 언어가 혼합 된 텍스트 필드를 사용할 때 flutter가 "Right-To-Left Mark"또는 "Left-To-Right Mark"에 대한 유니 코드 문자를 추가하는 것으로 나타났습니다. 이 추가 표시는 텍스트에 추가되는 유니 코드 문자입니다. 이 추가 문자로 인해 위의 정규식이 실패했습니다. 문제를 해결하려면 이러한 문자에 대해 replaceAll을 수행하면됩니다. 여기에서 더 많은 것을 읽으십시오 :https://github.com/flutter/flutter/issues/56514.

답변

2 wp78de Aug 20 2020 at 03:34

이것은 상당히 끔찍한 문제이며 여기에 답변을 문서화 할 가치가 있습니다.

소스에 설명 된대로 :

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

관련 : Flutter의 RTL (오른쪽에서 왼쪽)