在 Flutter 中使用正则表达式验证 URL,不需要它

Validate a URL, without requiring it, using a Regular Expression in Flutter

我正在 Flutter 中创建一个表单并需要以下功能:

  1. 如果用户输入 URL,我想用正则表达式确保它有效。
  2. 如果用户将该字段留空,我不想 return 一条错误消息。

当我执行这四个步骤时,以下 Reg Exp 验证器以这种方式执行:

就好像它只运行一次验证程序,然后就不会再次检查任何后续条目。 我确实有一个使用 value.isEmpty 作为验证器的字段,它确实按预期工作,每次我用 _formKey.currentState.save();

单击我的按钮时检查输入
child: TextFormField(
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Related URL',
              ),
              textInputAction: TextInputAction.next,
              keyboardType: TextInputType.url,
              focusNode: _relatedUrlFocusNode,
              onFieldSubmitted: (_) {
                FocusScope.of(context).requestFocus(_notesFocusNode);
              },
              //this doesn't work
              validator: (String value) {
                if (RegExp(r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
                        .hasMatch(value)) {
                  return 'Please enter a valid URL';
                }
                return null;
              },
              onSaved: (String value) {
                relatedUrl = value;
              },
            ),

...其他领域...

ElevatedButton(
            child: Text('ADD & ACTIVATE'),
            onPressed: () {
              if (!_formKey.currentState.validate()) {
                return;
              }
              ScaffoldMessenger.of(context)
                  .showSnackBar(SnackBar(content: Text('Processing Data')));
              _formKey.currentState.save();
            },
          )

我如何确保每次单击提交时它都执行验证程序?

您的代码有两个问题:

  1. 您的支票应该是 if (!RegExp(r"...").hasMatch(value)) {} 而不是 if (RegExp(r"...").hasMatch(value)) {}
  2. 您的正则表达式不正确。您可以查看 here。 (Dart 正则表达式与 Javascript 正则表达式相同)

validators package

的解决方案

您可以使用 validators package.

而不是 RegExp

便于复制粘贴的完整源代码:

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:validators/validators.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'URL Validation Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _formKey = useState(GlobalKey<FormState>());
    final _focusNode = useFocusNode();
    return Scaffold(
      body: Container(
        padding: EdgeInsets.all(8.0),
        alignment: Alignment.center,
        child: Form(
          key: _formKey.value,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextFormField(
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'URL',
                ),
                validator: (value) {
                  if (!isURL(value)) {
                    return 'Please enter a valid URL';
                  }
                  return null;
                },
              ),
              const SizedBox(height: 24.0),
              ElevatedButton(
                child: Text('VALIDATE'),
                onPressed: () {
                  if (_formKey.value.currentState.validate()) {
                    ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(content: Text('Processing Data')));
                  }
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}