Dart / Flutter - 验证字符串是否为URL

37

我正在尝试创建一个系统,以验证字符串是否为网址。(https://www.google.com/)

我找到了名为validator的flutter包,但它不兼容dart 2,因此无法与我的代码兼容。

名称相似的另一个包是validators,但我似乎无法将其与我的代码正常配合使用,因为它会抛出以下错误;(希望您喜欢我的项目名称 ;)

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)

如果您可以找到一种方法来修复validators,以便它不会抛出此错误并且能够正确地与我的代码配合工作,或者建议另一种验证字符串是否符合URL的方法,那就太好了。

谢谢

编辑 - 我的pubspec.yaml文件

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

你能给我一个例子吗? - Jake
1
尝试使用 Uri.parse(text);,如果URI无效,则应抛出异常。 - Günter Zöchbauer
1
使用这种方法创建一个字符串,这是我所需要的吗?String endResultConvert = Uri.parse(testResult); - Jake
你的pubspec.yaml文件长什么样子?听起来你可能有一个可解决的版本冲突问题。 - rmtmckenzie
请检查我的编辑,已添加我的 pubspec.yaml 文件。 - Jake
显示剩余3条评论
12个回答

40

要检查有效的URL字符串,您只需要使用Uri.parse(),如下所示。

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

只需检查_validURL的值即可。


17
对于字符串"http:",这也返回true。 - AmitB10
4
还有一个 Uri.tryParse 方法,如果 uri 字符串无效,它不会抛出异常。 - matwr
当我输入“google.com”时,它显示为false。当我输入“www.google.com”时,它也显示为false。只有当我输入“https://www.google.com/”时,它才显示为true。我该如何解决这个问题? - My Car
@MyCar,你的测试用例没有问题,只有在指定了协议等条件时,你的URL才被认为是有效的。 - Nickolas de Luca Alberton
@MyCar,你可以在你的URL前面添加“https://”来使其正常工作。 - akash maurya
这甚至会返回 true,即使 URL 中有未转义的字符,因为解析器会自动转义它们。这不是一个好的解决方案。 - EzPizza

31
Uri.tryParse(mystring)?.hasAbsolutePath ?? false;

一些示例结果:

网址 结果
'https://dev59.com/DFQJ5IYBdhLWcg3w2Jq8 true
asd false
asd:asd false
%EMPTY_STRING% false
google.nl false
https: false
https:// false
https://a false
https://a/ true

7
值得注意的是,对于“/”或任何不是http(s)(例如“ftp:/”)的其他Uri,这也将是正确的。如果您还想检查这一点,应该使用以下内容:final uri = Uri.tryParse('/'); final isValid = uri != null && uri.hasAbsolutePath && uri.scheme.startsWith('http'); - enyo
这甚至会返回true,即使URL中有未转义的字符,因为解析器会自动转义它们。这不是一个好的解决方案。 - EzPizza

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

你也可以使用 RegExp。


11
我使用了以下方法。根据您的建议,所有有效的URL都需要有一个主机(例如,google.com)。如果URL没有主机,则返回一个空字符串(而不是未定义或null)。
  bool isURLValid = Uri.parse('https://google.com/').host.isNotEmpty;

使用 .isAbsolute 方法,正如一些人已经报告的那样,会将诸如 'http:' 的 URL 标记为有效的 URL,但事实上并非如此。

9
由于某些原因,validators包需要一个相当新的Flutter测试库版本而不是让应用来决定。也许有一个很好的原因(即他们正在使用一项新功能)。
Flutter引擎内部需要特定版本的flutter_test库(这就是为什么指定它的版本通常是一个坏主意)。因此,要解决这个问题,您需要通过运行flutter upgrade来升级您的Flutter。如果您已经在所选渠道中处于最新版本,则可能需要运行flutter channel devflutter channel master以切换到更频繁更新的渠道/分支。
我大多数时间都在dev分支/频道上运行,虽然偶尔会出现问题,但并不经常。我建议尽量不要使用master分支。

现在正在尝试,我会尽快回复您。 - Jake
这个很好用,谢谢!现在可以正确使用Validators了。 - Jake

8

使用正则表达式进行验证

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;
}  

使用内置包进行验证

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

如果您需要验证特殊情况,例如必须验证深度链接(deepLink),则正则表达式是最佳实践。


2

对于正则表达式,如果你想在一个字符串中查找URL,可以使用这个。

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

当您需要在字符串中突出显示URL时,可以使用它。例如,在聊天应用程序中,您可以突出显示已发送的聊天消息中的URL。 这将验证google.com,https://google.comhttp://google.com


1
你好 @Ares,我已经尝试了你的正则表达式,但它无法验证 https://google.comhttp://google.comgoogle.com - R Rifa Fauzi Komara
我实际上正在使用它进行验证,而且它运行良好。请详细说明您如何尝试使用正则表达式。@RRifaFauziKomara - Ares

1
你可以使用url_launcher包来实现这个功能。
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;

解析器会针对无效的URL抛出异常,并通过自动转义特殊字符来解析URL。 - EzPizza

1
使用这个简单的函数,您可以确定字符串是否为有效的URL。
   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);  }

1

我正在使用这种方法验证URL。在您的TextFormField中,请使用此验证程序。在此处,您的URL应该以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;
                      }
                    },

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接