最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang實現(xiàn)驗證一個字符串是否為URL

 更新時間:2023年04月18日 10:22:25   作者:宇宙之一粟  
在實際開發(fā)過程中,有時候會遇到?URL?的校驗問題,Go?語言中有哪些方法去驗證一個字符串是否滿足?URL?格式呢?本文就來和大家詳細講講

前言

在實際開發(fā)過程中,有時候會遇到 URL 的校驗問題,其實我也是直接調用了第三方庫,但是也引發(fā)了一個思考,Go 語言中有哪些方法去驗證一個字符串是否滿足 URL 格式呢?

URL 代表唯一資源定位符,是 URI 的子類型(盡管許多人可以互換使用這兩個術語)。URL 是對網(wǎng)絡資源的引用,通常被視為網(wǎng)址(例如 https://golang.org)。

下面你可以看到一個 URL 的結構,它符合 URI 的結構

URI = scheme:[//authority]path[?query][#fragment]
authority = [userinfo@]host[:port]

官方 URL 包

在 Golang 中利用 url.ParseRequestURI 可以簡單驗證我們的 URL。

func ParseRequestURI(rawurl string) (*URL, error)

ParseRequestURI 將 rawurl 解析成 URL 結構。它假定在HTTP請求中接收到 rawurl,因此 rawurl 僅被解釋為絕對 URI 或絕對路徑。假定字符串 rawurl 沒有 #fragment 后綴。(Web 瀏覽器在將 URL 發(fā)送到 Web 服務器之前去除 #fragment。)

ParseRequestURI 與 Parse

還有另一種方法應該用于解析 URL 字符串,但有一些注意事項。它允許相對 URL 使驗證更加寬松。它是url.Parse

func Parse(rawurl string) (*URL, error)

如文檔中所述:

Parse 將 rawurl 解析成 URL 結構。
rawurl 可以是相對的(路徑,沒有主機)或絕對的(以方案開頭)。嘗試在沒有方案的情況下解析主機名和路徑是無效的,但由于解析歧義,不一定會返回錯誤。

比如如下的例子:

package main

import (
	"fmt"
	"net/url"
)

func main() {

	str := "http://yuzhou1u.com"

	var validURL bool

	_, err := url.Parse(str)

	if err != nil {
		fmt.Println(err)
		validURL = false
	} else {
		validURL = true
	}

	fmt.Printf("%s is a valid URL : %v \n", str, validURL)

}

使用 ParseRequestURI

在 Google 解決方法的時候,根據(jù)這篇教程中 How to check if a string is a valid URL in Golang? 提供的方法,寫了一個函數(shù):

func isValidUrl(u1 string) bool {

	_, err := url.ParseRequestURI(u1)
	if err != nil {
		return false
	}

	u, err := url.Parse(u1)
	if err != nil || u.Scheme == "" || u.Host == "" {
		return false
	}

	// Check if the URL has a valid scheme (http or https)
	if u.Scheme != "http" && u.Scheme != "https" {
		return false
	}

	return true
}

使用這個方法也有個缺陷,如果是多個 schema:https,也是檢查不出來的,例如下面的示例:

package main

import (
	"fmt"
	"net/url"
)

func main() {

	fmt.Println(isValidUrl("testURL"))

	fmt.Println(isValidUrl("test.test/"))

	fmt.Println(isValidUrl("http://goglang.org"))

	fmt.Println(isValidUrl("https://goglang.org"))

	fmt.Println(isValidUrl("https://https://https://../google.com"))
}

func isValidUrl(u1 string) bool {

	_, err := url.ParseRequestURI(u1)
	if err != nil {
		return false
	}

	u, err := url.Parse(u1)
	if err != nil || u.Scheme == "" || u.Host == "" {
		return false
	}

	// Check if the URL has a valid scheme (http or https)
	if u.Scheme != "http" && u.Scheme != "https" {
		return false
	}

	return true
}

運行結果如圖:

使用 url-verifier 包

安裝:go get -u github.com/davidmytton/url-verifier

package main

import (
	"fmt"

	urlverifier "github.com/davidmytton/url-verifier"
)

func main() {

	url := "https://https://https://../google.com"

	verifier := urlverifier.NewVerifier()

	ret, err := verifier.Verify(url)

	if err != nil {
		fmt.Errorf("Error: %s", err)
	}

	fmt.Printf("Result: %+v\n", ret)

}

運行結果:

后面在研究這部分 verifier.go 源碼時,發(fā)現(xiàn)這個用了 govalidator 這個包,如圖:

于是,我們何不直接使用 govalidator 包來判斷一個字符串是否是 URL 呢?

使用 govalidator 包

govalidator 是一個針對字符串、結構體和集合的驗證器和包?;?validator.js。

GitHub 地址:github.com/asaskevich/govalidator , 目前收獲了 5.7k 的 star

安裝:go get github.com/asaskevich/govalidator

package main

import (
	"fmt"

	"github.com/asaskevich/govalidator"
)

func main() {

	str := "https://https://https://../google.com"

	validURL := govalidator.IsURL(str)

	fmt.Printf("%s is a valid URL : %v \n", str, validURL)
}

運行結果如下:

正則表達式匹配

本來想自己寫正則表達式匹配的,然后發(fā)現(xiàn) govalidator 包的作者背后的原理也是用了正則表達式的,

然后就偷懶了,直接把他源碼中的部分集合到一個 main.go 函數(shù)中:

package main

import (
	"fmt"
	"net/url"
	"regexp"
	"strings"
	"unicode/utf8"
)

const (
	URLSchema    string = `((ftp|tcp|udp|wss?|https?):\/\/)`
	URLUsername  string = `(\S+(:\S*)?@)`
	URLPath      string = `((\/|\?|#)[^\s]*)`
	URLPort      string = `(:(\d{1,5}))`
	URLIP        string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3]|24\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-5]))`
	IP           string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
	URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))`
	URL                 = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$`

	/*MaxURLRuneCount : maxima cantidad de runas por contar*/
	MaxURLRuneCount = 2083
	/*MinURLRuneCount : minima cantidad de runas por contar*/
	MinURLRuneCount = 3
)

var rxURL = regexp.MustCompile(URL)

// IsURL checks if the string is an URL.
func IsURL(str string) bool {
	if str == "" || utf8.RuneCountInString(str) >= MaxURLRuneCount || len(str) <= MinURLRuneCount || strings.HasPrefix(str, ".") {
		return false
	}
	strTemp := str
	if strings.Contains(str, ":") && !strings.Contains(str, "://") {
		// support no indicated urlscheme but with colon for port number
		// http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString
		strTemp = "http://" + str
	}
	u, err := url.Parse(strTemp)
	if err != nil {
		return false
	}
	if strings.HasPrefix(u.Host, ".") {
		return false
	}
	if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
		return false
	}
	return rxURL.MatchString(str)
}

func main() {

	fmt.Println(IsURL("testURL"))

	fmt.Println(IsURL("test.test/"))

	fmt.Println(IsURL("http://goglang.org"))

	fmt.Println(IsURL("https://goglang.org"))

	fmt.Println(IsURL("https://https://https://../google.com"))
}

運行結果:

除了校驗 URL,這個包還提供了眾多的字符串校驗方法,例如校驗郵箱、信用卡格式、IP...

總結

數(shù)據(jù)校驗是每個程序員日常開發(fā)過程的一部分,尤其是在從事后端服務時,數(shù)據(jù)驗證必須嚴格,保持正確。

在這篇文章中,我們討論了如何在 Go 語言中正確驗證一個字符串是否是 URL,當然利用了官方包和優(yōu)秀的第三方包,在實際過程中,可能我們?yōu)榱撕啽銜苯邮褂脛e人開發(fā)好的工具,但是在學習過程中,不妨也去思考別人實現(xiàn)的原理,結合實際業(yè)務需要,進而擴展成自己的工具包。

以上就是Golang實現(xiàn)驗證一個字符串是否為URL的詳細內容,更多關于Golang驗證字符串是否為URL的資料請關注腳本之家其它相關文章!

相關文章

  • 使用Go語言開發(fā)自動化API測試工具詳解

    使用Go語言開發(fā)自動化API測試工具詳解

    這篇文章主要為大家詳細介紹了如何使用Go語言開發(fā)自動化API測試工具,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2024-03-03
  • Go語言中的sync包同步原語最新詳解

    Go語言中的sync包同步原語最新詳解

    Go語言在sync包中提供了一套多才多藝的同步機制,以及用于管理對共享資源的并發(fā)訪問的原子操作,了解這些工具并為您的并發(fā)需求選擇合適的工具是編寫高效可靠的并發(fā)Go程序的關鍵,這篇文章主要介紹了Go語言中的`sync`包同步原語,需要的朋友可以參考下
    2023-12-12
  • GO語言實現(xiàn)簡單的目錄復制功能

    GO語言實現(xiàn)簡單的目錄復制功能

    這篇文章主要介紹了GO語言實現(xiàn)簡單的目錄復制功能,通過新建及復制內容等操作最終實現(xiàn)復制目錄的功能效果,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • Golang實現(xiàn)自定義時間結構體并支持Json&Gorm

    Golang實現(xiàn)自定義時間結構體并支持Json&Gorm

    因為時區(qū)等問題,很多項目需要自定義時區(qū)和時間格式,所以這篇文章主要為大家介紹了Golang如何實現(xiàn)自定義時間結構體并支持Json&Gorm,希望對大家有所幫助
    2024-03-03
  • 代碼之美:探索Go語言斷行規(guī)則的奧秘

    代碼之美:探索Go語言斷行規(guī)則的奧秘

    Go語言是一門以簡潔、清晰和高效著稱的編程語言,而斷行規(guī)則是其代碼風格的重要組成部分,通過深入研究Go語言的斷行規(guī)則,我們可以更好地理解和編寫優(yōu)雅的代碼,本文將從語法規(guī)范、代碼風格和最佳實踐等方面進行探討,幫助讀者更好地理解和應用Go語言的斷行規(guī)則
    2023-10-10
  • Go語言使用Buffer實現(xiàn)高性能處理字節(jié)和字符

    Go語言使用Buffer實現(xiàn)高性能處理字節(jié)和字符

    在?Go?中,bytes.Buffer?是一個非常高效的類型,用于處理字節(jié)數(shù)據(jù)的讀寫操作,本文將詳細介紹一下如何使用Buffer實現(xiàn)高性能處理字節(jié)和字符,有需要的小伙伴可以了解下
    2025-01-01
  • 一文詳解Go語言中的Option設計模式

    一文詳解Go語言中的Option設計模式

    這篇文章主要為大家詳細介紹了Go語言中Option設計模式的相關知識,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的可以了解一下
    2023-05-05
  • GO語言判斷一個網(wǎng)段是否屬于另一個網(wǎng)段的子網(wǎng)

    GO語言判斷一個網(wǎng)段是否屬于另一個網(wǎng)段的子網(wǎng)

    這篇文章主要介紹了GO語言判斷一個網(wǎng)段是否屬于另一個網(wǎng)段的子網(wǎng)的相關資料,內容介紹詳細,具有一定的參考價值,需要的朋友可任意參考一下
    2022-03-03
  • Go錯誤處理的幾種方式

    Go錯誤處理的幾種方式

    在Go語言中,錯誤處理是一種重要的編程模式,它用于處理可能出現(xiàn)的錯誤或異常情況,本文就來介紹一下Go錯誤處理的幾種方式,感興趣的可以了解一下
    2023-11-11
  • 深入解析Go語言中HTTP請求處理的底層實現(xiàn)

    深入解析Go語言中HTTP請求處理的底層實現(xiàn)

    本文將詳細介紹?Go?語言中?HTTP?請求處理的底層機制,包括工作流程、創(chuàng)建?Listen?Socket?監(jiān)聽端口、接收客戶端請求并建立連接以及處理客戶端請求并返回響應等,需要的朋友可以參考下
    2023-05-05

最新評論

潞城市| 岗巴县| 怀宁县| 龙门县| 崇州市| 青神县| 阳江市| 吉首市| 南靖县| 南召县| 开鲁县| 楚雄市| 青神县| 通化县| 合阳县| 冕宁县| 泰宁县| 温泉县| 兴业县| 嵊泗县| 阜平县| 雷波县| 雷州市| 道真| 会泽县| 佛教| 汝州市| 嘉峪关市| 龙州县| 通化市| 大邑县| 桦南县| 合作市| 上饶市| 潮安县| 涞水县| 沛县| 大埔区| 怀宁县| 监利县| 浠水县|