Dart / Flutter - Validating a string for URL
Asked Answered
D

13

41

I'm trying to create a system in which I can validate a string to check if it's a url or not. (https://www.google.com/)

I found the flutter package validator but this isn't dart 2 compatible, so won't be compatible with my code.

Similarly named, I also found the validators package but I can't seem to get it working correctly with my code, as it throws the following error; (hope you like my project name ;)

Because every version of flutter_test from sdk depends on test 1.3.0 
and every version of validators depends on test ^1.3.3, flutter_test from sdk is incompatible with validators.
So, because gucci depends on both validators ^1.0.0+1 and flutter_test any from sdk, version solving failed.
Unable to reload your application because "flutter packages get" failed to update package dependencies.
Exception: pub get failed (1)

If you could either find a fix for validators so that it doesn't throw this error and thus works correctly with my code, or suggest another method of validating a string to be URL compliant that would be great.

Thanks

Edit - My pubspec.yaml file

name: gucci
description: A new Flutter project.

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons:
  barcode_scan:
  gradient_app_bar:
  url_launcher:
  validate: ^1.7.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  fonts:
    - family: PlayfairDisplay
      fonts:
        - asset: fonts/PlayfairDisplay-BoldItalic.ttf

    - family: Kanit
      fonts:
        - asset: fonts/Kanit-ExtraBoldItalic.ttf

    - family: Poppins
      fonts:
        - asset: fonts/Poppins-BoldItalic.ttf

    - family: PoppinsLightItalic
      fonts:
        - asset: fonts/Poppins-LightItalic.ttf

    - family: PoppinsMediumItalic
      fonts:
        - asset: fonts/Poppins-MediumItalic.ttf
Deport answered 24/10, 2018 at 18:27 Comment(8)
What about Uri.html(...)?Incipit
Could you give me an example?Deport
That's what I found out. I'm trying print(new Uri.http("$text", ""),); just to return an output, but I don't know how to validate as stated in my original questionDeport
Try Uri.parse(text); It should throw an exception if the URI is not valid.Incipit
Creating a string using this method, is this what I would need? String endResultConvert = Uri.parse(testResult);Deport
What does your pubspec.yaml look like? It sounds like you have a version conflict that might be solvable.Litton
Please check my edit, added my pubspec.yaml fileDeport
@Litton did you manage to take a look at my edit?Deport
L
9

For some reason, the validators package is requiring a pretty recent version of flutter's testing library rather than leaving it up to the application. Maybe there's a good reason for that (i.e. they're using a new feature).

The flutter engine internally requires a particular version of the flutter_test library (which is why it's generally a bad idea to specify a version of it). So to fix this you'll have to upgrade your flutter by running flutter upgrade. If you're already at the most recent version of the channel you're in, you may have to run flutter channel dev or flutter channel master to switch to a channel (branch really) that's updated more often.

I run on the dev branch/channel for the most part and while it very occasionally has problems, it doesn't happen a lot. I'd advise against using the master branch if possible though.

Litton answered 29/10, 2018 at 14:49 Comment(2)
Trying this now, I'll get back to you ASAP.Deport
This worked well thanks! Now getting a proper use of ValidatorsDeport
M
45

To check Valid URL string you just have to use Uri.parse() like below.

bool _validURL = Uri.parse(_adVertData.webLink).isAbsolute;

Just check value of _validURL

Mercier answered 4/10, 2019 at 15:40 Comment(6)
This also returns true for string "http:".Rapping
There is also Uri.tryParse which does not throw an Exception in case of invalid uri string.Minimal
When I type "google.com" it shows me false. When I type "www.google.com" it shows me false. When I type "https://www.google.com/" it shows me true. How can I fix this problem?Thymol
@MyCar there is no problem with your test case, your url is considered valid only if the protocol, among other things, is specified.Kirovograd
@MyCar, you can add "https://" in front of you URL to make this work.Tinker
This even returns true if there are unescaped characters in the URL, because the parser automatically escapes them. That's not a good solution.Figurant
B
33
Uri.tryParse(mystring)?.hasAbsolutePath ?? false;

Some example results:

url result
'https://mcmap.net/q/389708/-dart-flutter-validating-a-string-for-url' true
asd false
asd:asd false
%EMPTY_STRING% false
google.nl false
https: false
https:// false
https://a false
https://a/ true
Brevier answered 9/5, 2021 at 16:2 Comment(2)
It's worth noting that this will also be true for / or any other Uri that is not http(s) (like ftp:/). If you want to check for this as well, it should be: final uri = Uri.tryParse('/'); final isValid = uri != null && uri.hasAbsolutePath && uri.scheme.startsWith('http');Kilar
This even returns true if there are unescaped characters in the URL, because the parser automatically escapes them. That's not a good solution.Figurant
D
16
var urlPattern = r"(https?|http)://([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:‌​,.;]*)?";
var match = new RegExp(urlPattern, caseSensitive: false).firstMatch('https://www.google.com');

You can use RegExp too.

Dorothadorothea answered 14/4, 2019 at 11:28 Comment(0)
S
13

I used the following method below. Depending on your rec, all valid URLs need to have a host (ex, google.com). If a URL does not have a host it returns an empty string (not undefined or null).

  bool isURLValid = Uri.parse('https://google.com/').host.isNotEmpty;

Using .isAbsolute, as some have already reported, marks URLs such as 'http:' to be valid URLs which not.

Solve answered 23/7, 2021 at 18:9 Comment(0)
L
9

For some reason, the validators package is requiring a pretty recent version of flutter's testing library rather than leaving it up to the application. Maybe there's a good reason for that (i.e. they're using a new feature).

The flutter engine internally requires a particular version of the flutter_test library (which is why it's generally a bad idea to specify a version of it). So to fix this you'll have to upgrade your flutter by running flutter upgrade. If you're already at the most recent version of the channel you're in, you may have to run flutter channel dev or flutter channel master to switch to a channel (branch really) that's updated more often.

I run on the dev branch/channel for the most part and while it very occasionally has problems, it doesn't happen a lot. I'd advise against using the master branch if possible though.

Litton answered 29/10, 2018 at 14:49 Comment(2)
Trying this now, I'll get back to you ASAP.Deport
This worked well thanks! Now getting a proper use of ValidatorsDeport
H
9

Validation using RegEx

String hasValidUrl(String value) {
   String pattern = r'(http|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?';
   RegExp regExp = new RegExp(pattern);
   if (value.length == 0) {
        return 'Please enter url';
   }
   else if (!regExp.hasMatch(value)) {
     return 'Please enter valid url';
   }
   return null;
}  

Validation using in-built package

final Uri uri = Uri.tryParse(value);
if (!uri.hasAbsolutePath) {
     return 'Please enter valid url';
}

If you want some special case like you have to validate deepLink then RegEx practice is best.

Hedgerow answered 12/11, 2021 at 4:39 Comment(0)
B
2

For RegExp, if you are going to find URL in a string, you can use this one.

r'^((?:.|\n)*?)((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:‌​,.;]*)?)'

It can be used when you are highlighting URL in a string. For example in a chat app, you can highlight URL in a sent chat message. This validates google.com, https://google.com, http://google.com all.

Broadloom answered 27/2, 2020 at 20:35 Comment(2)
Hi @Ares, I already try your regex but it's not validates for https://google.com and http://google.com and google.comFreighter
I am actually using this for my validation and it's working fine. Plz specify in detail how you are trying to use regex. @RRifaFauziKomaraBroadloom
C
1

I'm using this way to validate Urls. In your TextFormField's use this validator. here your url should be start from www.

validator: (website) {
                      String pattern =
                          r'^((?:.|\n)*?)((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:‌​,.;]*)?)';
                      RegExp regExp = RegExp(pattern);
                      if (website.isEmpty) {
                        return "Please enter your website";
                      } else if (!(regExp.hasMatch(website))) {
                        return "Website Url must be started from www";
                      } else {
                        return null;
                      }
                    },
Calorie answered 3/1, 2022 at 11:28 Comment(0)
H
1

You can use the url_launcher package for this.

Future<bool> checkIfUrlIsValid({required String url}) async {
if (await canLaunchUrl(Uri.parse(url))) {
  return true;
}
return false;}


checkIfUrlIsValid(url: 'https://google.com'); // true;
checkIfUrlIsValid(url: 'google com'); // false;
Hexyl answered 21/7, 2022 at 19:33 Comment(1)
parse will throw an exception for invalid URLs and it also parses URLs with special characters by escaping them automatically.Figurant
S
1

Use this simple function then you can identify string is valid URL or not

   bool isURl(String url){
return  RegExp(r'^((?:.|\n)*?)((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:‌​,.;]*)?)')
    .hasMatch(url);  }
Songsongbird answered 17/8, 2022 at 19:3 Comment(0)
F
0
TextEditingController urlController = TextEditingController();
String urlData = '';
static final GlobalKey<FormFieldState<String>> _orderFromkey =
GlobalKey<FormFieldState<String>>(); 

@override Widget build(BuildContext context) { return SafeArea( child: Scaffold( resizeToAvoidBottomInset: false,

        body: Column(
          children: [
            appBar(label: appName),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextFormField(
                key: _orderFromkey,
                controller: urlController,
                validator: (value) {
                  String patttern =  r"((https?:www\.)|(https?:\/\/)|(www\.))[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9]{1,6}(\/[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)?";
                  RegExp regExp = new RegExp(patttern);
                if (!regExp.hasMatch(value!)) {
                    return 'Please enter valid URL';
                  }
                },




                decoration: InputDecoration(

                    fillColor: appColor,
                    labelText: "url",
                    labelStyle: new TextStyle(color: appColor),
                    contentPadding: EdgeInsets.only(left: 10, right: 10),
                    enabledBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: appColor),
                    ),
                    focusedBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: black),
                    ),
                    hintText: 'Enter Your URL'),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: InkWell(
                onTap: () {
                  print('_orderFromkey: ${_orderFromkey}');
                  final FormFieldState<String>? form =
                      _orderFromkey.currentState;
                  if (form!.validate()) {
                    urlData = urlController.text;
                    Get.toNamed('/showQr', arguments: urlData);
                    print('text : ${urlData}');
                  } else {
                    // _autoValidation = true;
                  }
                },
                child: Container(
                  width: ScreenSize.size.width * 0.6,
                  height: ScreenSize.size.height * 0.1,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10),
                    color: appColor,
                  ),
                  child: const Align(
                      alignment: Alignment.center,
                      child: Text(
                        'Submit',
                        style: TextStyle(
                            fontSize: 20,
                            color: white,
                            fontWeight: FontWeight.w700),
                        textAlign: TextAlign.center,
                      )),
                ),
              ),
            ),
          ],
        )),
  );

}

Furring answered 16/6, 2022 at 2:22 Comment(0)
P
0

If you are using GetX, it provides a string extension called "isURL":

import 'package:get/get.dart';

final url = 'https://www.google.com/';

if (url.isURL) {
  print('Success');
}

Note: you should not install this plugin if you will only use this extension, the idea is to take advantage of it if you already use it.

More String extensions from GetX:

  • isNum
  • isNumericOnly
  • isAlphabetOnly
  • isBool
  • isDocumentFileName
  • isExcelFileName
  • isEmail
  • isPhoneNumber
  • isDateTime

And others.

See: https://github.com/jonataslaw/getx/blob/master/lib/get_utils/src/extensions/string_extensions.dart

Pennant answered 12/6, 2023 at 14:46 Comment(0)
M
0

use this and no more search

    String
    pattern =
    r'((http|https)://)|(www.)+([\w.,@?^=%&amp;:/~+#-]*[\w@?^=%&amp;/~+#-])+(?:\.[a-zA-Z]{2,})+(?:\/[^\s]*)?$';
    RegExp
    regExp =
    RegExp(
    pattern);
    if (value ==
    '') {
    return 'Please enter url';
    } else if (!regExp
    .hasMatch(
    value.toString())) {
    return 'Please enter valid url';
    }
    return null;
Milne answered 23/1 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.