regex 在TextFormField的输入格式化程序中仅用于正整数和负整数的正则表达式

4nkexdtk  于 2023-05-01  发布在  其他
关注(0)|答案(3)|浏览(88)

我试图有一个TextFormField只接受5位数的负数和正数。
下面的代码,但它只限制数字,最多5位,但它不接受负号。

new TextFormField(
    maxLines: 1,
    keyboardType: TextInputType.number,
    enableSuggestions: false,
    inputFormatters: [
        LengthLimitingTextInputFormatter(5),
        FilteringTextInputFormatter.allow(RegExp(r'-?[0-9]')),
    ],
    onChanged: (val) {},
);

我试过下面的regex:“-?[0-9]”,但不允许使用负号。

ui7jx7zq

ui7jx7zq1#

使用输入过滤器的问题是每个中间字符串也必须与过滤器匹配。由于您的过滤器在输入“-3”的过程中无法匹配减号“,因此它不起作用。
这时您必须放弃使用输入过滤器,而是将验证放入验证器中,验证器仅在检查时应用,并且不会阻止中间组合在途中输入。

qvk1mo1f

qvk1mo1f2#

RegExp(r'-?[0-9]')更改为RegExp(r'-?[0-9]*')。它不允许你输入一个“-”,因为你的表达式是说你必须有一个数字,但只是“-”无效,所以格式化程序不允许你输入负数。

cnwbcb6i

cnwbcb6i3#

如@randal-schwartz所示,格式化器评估每个新输入,这导致每个中间字符串都将匹配过滤器,包括开始键入负数时,并且减号“-”单独不匹配正则表达式。
此外,根据FilteringTextInputFormatter的文档,此格式化器不应用于匹配整个字符串的模式(例如,包含位置匹配器(^$)的[RegExp])。

溶液

使用TextInputFormatter和一个函数来检查输入是否可以被解析成Int,否则返回之前的输入。

new TextFormField(
    maxLines: 1,
    keyboardType: TextInputType.number,
    enableSuggestions: false,
    inputFormatters: [
        TextInputFormatter.withFunction((oldV, newV) => onlyIntegersFormatter(oldV, newV, 5)),
    ],
    onChanged: (val) {},
);
static TextEditingValue onlyIntegersFormatter(final TextEditingValue oldValue, final TextEditingValue newValue, {final int? digits}) {
    if (newValue.text.isEmpty || newValue.text == '-') {
      return newValue;
    } else {
      // Check if the input can be parsed into an Int and returns the 
      previous input otherwise.
      final int? newVal = int.tryParse(newValue.text);

      if (newVal == null) {
        return oldValue;
      } else {
        // Check for number of digits.
        if (digits != null) {
          return  math.pow(10, digits+1) < newVal ? newValue : oldValue;
        }
        return newValue;
      }
    }
};

备选方案

如果Regex仍然是解决方案:

new TextFormField(
    maxLines: 1,
    keyboardType: TextInputType.number,
    enableSuggestions: false,
    inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r'^-?\d{0,5}')),
    ],
    onChanged: (val) {},
);

正则表达式的解释:

  • ^:匹配输入字符串的开头。
    • ?:匹配“-”符号0次或1次。
  • \d{1,5}:匹配0到5位数。\d速记字符类匹配任何数字。

相关问题