DartRegExpの空白が認識されない
Aug 19 2020
英語の文字、アラビア文字、数字、ダッシュ、スペースを許可するユーザー名の正規表現パターンを実装しようとしています。
次のパターンは、\ sがパターンに含まれていても、入力文字列にスペースがある場合、常に一致を返しません。
Pattern _usernamePattern = r'^[a-zA-Z0-9\u0621-\u064A\-\s]{3,30}$';
また、\ sを ""と\\ sに置き換えようとしましたが、正規表現は、スペースを含む入力に対して常に一致を返しません。
編集:LTRまたはRTLに対応する言語が混在するテキストフィールドを使用すると、フラッターによって「右から左へのマーク」または「左から右へのマーク」にUnicode文字が追加されることがわかりました。この追加のマークは、テキストに追加されるUnicode文字です。上記の正規表現は、この追加の文字が原因で失敗していました。この問題を解決するには、これらの文字に対して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}');
}
関連:フラッターの右から左(RTL)