Hangi karakterler URL'yi geçersiz kılar?
Bu geçerli URL'ler mi?
example.com/file[/].html
http://example.com/file[/].html
Hangi karakterler URL'yi geçersiz kılar?
Bu geçerli URL'ler mi?
example.com/file[/].html
http://example.com/file[/].html
Yanıtlar:
Genel olarak RFC 3986 tarafından tanımlanan URI'lar (bkz. Bölüm 2: Karakterler ) aşağıdaki 84 karakterden herhangi birini içerebilir:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
Bu listenin bu karakterlerin URI'de nerede olabileceğini belirtmediğini unutmayın.
Diğer karakterlerin yüzde kodlaması ( %
hh
) ile kodlanması gerekir . URI'nin her bir parçasının yüzde olarak kodlanmış bir sözcükle hangi karakterlerin temsil edilmesi gerektiği konusunda daha fazla kısıtlaması vardır.
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
Kabul ettiğine karar verdiğiniz başka bir şey var mıydı? (Dize dize iyi oluşturulmuş URL içeren değilse, geçerli URL karakterler içeriyorsa Sadece bu regex sadece kontroller açık olmak.)
Biraz açıklama eklemek ve yukarıdaki soruyu doğrudan ele almak için, URL'ler ve URI'ler için sorunlara neden olan birkaç karakter sınıfı vardır.
İzin verilmeyen ve hiçbir zaman bir URL / URI'de, ayrılmış karakterlerde (aşağıda açıklanmıştır) ve bazı durumlarda sorunlara neden olabilecek, ancak "mantıksız" veya "güvensiz" olarak işaretlenmiş diğer karakterler vardır. Karakterlerin neden kısıtlandığına ilişkin açıklamalar RFC-1738 (URL'ler) ve RFC-2396'da (URI'ler) açıkça belirtilmiştir . Daha yeni RFC-3986'nın ( RFC-1738'e güncelleme) belirli bir bağlamda hangi karakterlere izin verildiğini tanımladığını, ancak eski özelliklerin aşağıdaki kurallarla hangi karakterlere izin verilmediğini daha basit ve daha genel bir açıklama sunduğunu unutmayın.
URI sözdizimi içinde izin verilmeyen ABD-ASCII Karakterlerine izin verilmiyor:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
"#" Karakteri, bir URI'yi parça tanımlayıcısından ayırmak için kullanıldığından hariç tutulur. Kaçan karakterlerin kodlanması için kullanıldığından "%" yüzde karakteri hariç tutulur. Başka bir deyişle, "#" ve "%" belirli bir bağlamda kullanılması gereken ayrılmış karakterlerdir.
Mantıksız karakterlerin listesine izin verilir, ancak sorunlara neden olabilir:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
Olan karakterler saklıdır sorgu bileşeni ve / veya içinde URI / URL içindeki özel bir anlamı vardır:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
Yukarıdaki "ayrılmış" sözdizimi sınıfı, bir URI içinde izin verilen, ancak genel URI sözdiziminin belirli bir bileşeni içinde izin verilmeyen karakterleri ifade eder. "Ayrılmış" kümesindeki karakterler tüm bağlamlarda ayrılmaz . Örneğin, ana bilgisayar adı isteğe bağlı bir kullanıcı adı içerebilir, böylece ftp://user@hostname/
'@' karakterinin özel bir anlamı olduğu bir şey olabilir .
Geçersiz ve mantıksız karakterleri (ör. '$', '[', ']') Olan ve düzgün şekilde kodlanması gereken bir URL örneği:
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
URI'ler / URL'ler için bazı karakter kısıtlamaları programlama diline bağlıdır. Örneğin, '|' (0x7C) karakteri yalnızca URI spesifikasyonunda "unwise" olarak işaretlenmiş olmasına rağmen , Java java.net.URI yapıcısına bir URISyntaxException kurar , böylece benzer bir URL'ye izin verilmez ve bunun yerine Java'nın bir URI nesnesi örneğiyle kullanılması gibi kodlanması gerekir .http://api.google.com/q?exp=a|b
http://api.google.com/q?exp=a%7Cb
?
gayet güzel de ondan önce sorgu bölümünde, ancak imkansız ve ben sanmıyorum @
bu listelerin herhangi aittir. Oh, ve %25
son ip yerine, demek istemiyor musun %7C
?
Buradaki mevcut cevapların çoğu pratik değildir, çünkü aşağıdaki gibi adreslerin gerçek dünya kullanımını tamamen görmezden gelirler:
İlk olarak, terminolojiye bir bakış. Ne olduğunu bu adresler? Geçerli URL'ler mi?
Tarihsel olarak, cevap "hayır" dı. RFC 3986'ya göre , 2005'ten itibaren bu tür adresler URI değildir (bu nedenle URL'ler bir tür URI olduğu için URL'ler değildir ). 2005 IETF standartlarının terminolojisine göre , teknik olarak URI olmayan ancak IRI'deki ASCII olmayan tüm karakterlerin yüzde kodlamasıyla URI'lara dönüştürülebilen RFC 3987'de tanımlandığı gibi, onlara IRI'ler (Uluslararası Kaynak Tanımlayıcıları) uygun şekilde çağırmalıyız. .
Modern teknik özelliklere göre, cevap "evet" tir. WHATWG Yaşam Standardı basitçe önce "URL'ler" olarak "URI'ları" veya "IRI'leri" denebilecek her şeyi sınıflandırır. Bu, belirtilen terminolojiyi, spesifikasyonu okumamış normal kişilerin, spesifikasyonun hedeflerinden biri olan "URL" kelimesini nasıl kullandığına uygun hale getirir .
"URL" nin bu yeni anlamı uyarınca, hangi karakterlere izin verilir? Böyle sorgu dizesi ve yol olarak URL'ye birçok yerinde, olarak, keyfi kullanım izni olan "URL birimleri" vardır,
"URL kodu noktaları" nedir?
URL kod noktaları + 0021 U (!), + 0024 U ($), + 0026 U (&), + 0027 U ( '), U + 0028 sol parantez U + 0029 sağ parantez U + ASCII alfanümerik vardır 002A (*), U + 002B (+), U + 002C (,), U + 002D (-), U + 002E (.), U + 002F (/), U + 003A (:), U + 003B (;), U + 003D (=), U + 003F (?), U + 0040 (@), U + 005F (_), U + 007E (~) ve U + 00A0 ila U aralığındaki kod noktaları + 10FFFD, dahil, suretler ve karakter olmayanlar hariç.
("URL kod noktaları" listesinin içermediğini %
, ancak %
yüzde kodlama sırasının bir parçasıysa "URL kod birimleri" nde bunlara izin verildiğini unutmayın.)
Spesifikasyonun bu kümede olmayan herhangi bir karakterin kullanılmasına izin verdiği yeri tespit edebileceğim tek yer , IPv6 adreslerinin ve karakterlerin bulunduğu ana bilgisayardadır . URL'nin her yerinde, URL birimlerine veya daha da kısıtlayıcı bir karakter kümesine izin verilir.[
]
Tarih uğruna ve buradaki cevaplarda başka bir yerde tam olarak araştırılmadığından, daha eski özelliklerin altında incelenmesine izin verelim.
Her şeyden önce, iki tür RFC 3986 ayrılmış karakteri var :
:/?#[]@
RFC 3986'da tanımlanan bir URI için genel sözdiziminin bir parçası olan!$&'()*+,;=
RFC'nin genel sözdiziminin bir parçası olmayan ancak belirli URI şemalarının sözdizimsel bileşenleri olarak kullanılmak üzere ayrılmıştır. Örneğin, noktalı ve virgül sözdizimi bir parçası olarak kullanılan veri URI'lar ve &
ve =
her yerde bir parçası olarak kullanılan ?foo=bar&qux=baz
(sorgu dizeleri biçiminde değildir RFC 3986 tarafından belirlenir).Yukarıdaki ayrılmış karakterlerden herhangi biri, sözdizimsel amaçlarına hizmet etmek için kodlama yapmadan veya bu tür bir kullanımın sözdizimsel amacına hizmet eden karakter olarak yanlış yorumlanamayacağı bazı yerlerde verilerdeki değişmez karakterler olarak yasal olarak bir URI'de kullanılabilir. (Örneğin, /
bir URL'de sözdizimsel anlamı olmasına rağmen , bir sorgu dizesinde kodlanmamış olarak kullanabilirsiniz, çünkü bir sorgu dizesinde anlamı yoktur .)
RFC 3986 de bazı belirten ayrılmamış hep Kodlama olmadan verileri temsil etmek basitçe kullanılabilecek karakterler,:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
Son olarak, %
yüzde kodlamaları için karakterin kendisine izin verilir.
Bu, yalnızca bir URL'de görünmesi yasaklanan aşağıdaki ASCII karakterlerini bırakır :
"<>\^`{|}
ASCII'deki diğer tüm karakterler yasal olarak bir URL'de yer alabilir.
Daha sonra RFC 3987, kaydedilmemiş karakter kümesini aşağıdaki unicode karakter aralıklarıyla genişletir:
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
En son Unicode blok tanımları göz önüne alındığında, eski spesifikasyondaki bu blok seçimleri tuhaf ve keyfi görünüyor ; bunun nedeni muhtemelen RFC 3987'nin yazılmasından bu yana blokların on yıl içinde eklenmiş olmasıdır.
Son olarak, bir URL'de hangi karakterlerin yasal olarak görünebileceğini bilmenin, bazı karakterlerin yalnızca URL'nin belirli bölümlerinde yasal olması nedeniyle belirli bir dizenin yasal bir URL olup olmadığını anlamak için yeterli olmadığını belirtmek gerekebilir. Örneğin, ayrılmış karakterler [
ve http: // [1080 :: 8: 800: 200C: 417A] / foo]
gibi bir URL'deki IPv6 değişmez ana bilgisayarının bir parçası olarak yasaldır, ancak başka bir bağlamda yasal değildir. OP'nin örneği yasadışı.http://example.com/file[/].html
Ek sorunuzda www.example.com/file[/].html
geçerli bir URL olup olmadığını sordunuz .
Bir URL bir URI türü olduğu ve geçerli bir URI'nin şemaya sahip olması gerektiğinden bu URL geçerli değildir http:
(bkz. RFC 3986 ).
http://www.example.com/file[/].html
Geçerli bir URL olup olmadığını sormak istiyorsan , cevap hala hayır çünkü köşeli ayraç karakterleri orada geçerli değil.
Köşeli ayraç karakterleri şu biçimdeki URL'ler için ayrılmıştır: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(ana bilgisayar adı yerine IPv6 değişmez değeri)
Sorunu tam olarak anlamak istiyorsanız RFC 3986'yı dikkatlice okumaya değer.
[
Ve ]
gördüğüm neredeyse ayrıştırıcıları için geçerli bir URI değildir. Bu beni gerçek dünyaya
Unwise
URI'ler için çok ciddiye alacak ve yine de URL kütüphaneleri ile iyi olacak Python, C #, Java ve bazı C kütüphanelerinden. Görmezden gelinecek bir bayrak yok Unwise
. URL'ler için Rust lang (bir tarayıcı için üretildiğinden beri ne yaptığını merak ediyorum) kontrol etmeliyim. Yine de çoğu tarayıcı mutlu bir şekilde "[", "]" iletecektir. Teoride C / C ++ ile söylediğim gibi alt / süper ama gerçek o kadar da doğru değil. Süper / altkümenin özelliklerinin ve anlambiliminin yorumlanmasına büyük ölçüde bağımlıdır.
Bir URI'de kullanılabilen tüm geçerli karakterler ( URL , bir URI türüdür ) RFC 3986'da tanımlanmıştır .
Diğer tüm karakterler, önce "URL Kodlamalı" olmaları koşuluyla bir URL'de kullanılabilir. Bu, belirli "kodlar" için geçersiz karakterin değiştirilmesini içerir (genellikle yüzde sembolü (%) ve ardından onaltılı sayı biçiminde).
Bu bağlantı, HTML URL Kodlama Referansı , geçersiz karakterler için kodlamaların bir listesini içerir.
Unicode karakter aralıklarının birçoğu geçerli HTML5'tir , ancak yine de bunları kullanmak iyi bir fikir olmayabilir.
Örneğin, href
dokümanlar http://www.w3.org/TR/html5/links.html#attr-hyperlink-href diyor :
A ve alan öğelerindeki href özelliği, potansiyel olarak boşluklarla çevrili geçerli bir URL olan bir değere sahip olmalıdır.
Sonra, "geçerli bir URL" noktalarının tanımı http://url.spec.whatwg.org/ diyor, bu amaçlar:
RFC 3986 ve RFC 3987'yi çağdaş uygulamalarla hizalayın ve bunları eski haline getirin.
Bu belge URL kodu noktalarını şu şekilde tanımlar :
ASCII alfasayısal, "!", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/" , ":", ";", "=", "?", "@", "_", "~" ve U + 00A0 - U + D7FF, U + E000 - U + FDCF arasındaki kod noktaları , U + FDF0 - U + FFFD, U + 10000 - U + 1FFFD, U + 20000 - U + 2FFFD, U + 30000 - U + 3FFFD, U + 40000 - U + 4FFFD, U + 50000 - U + 5FFFD, U +60000 - U + 6FFFD, U + 70000 - U + 7FFFD, U + 80000 - U + 8FFFD, U + 90000 - U + 9FFFD, U + A0000 - U + AFFFD, U + B0000 - U + BFFFD, U + C0000 U + CFFFD, U + D0000 - U + DFFFD, U + E1000 - U + EFFFD, U + F0000 - U + FFFFD, U + 100000 - U + 10FFFD.
"URL kod noktaları" terimi daha sonra ifadede kullanılır:
C bir URL kodu noktası değilse ve "%" değilse, ayrıştırma hatası.
şema, yetki, göreceli yol, sorgu ve parça durumları da dahil olmak üzere ayrıştırma algoritmasının birkaç bölümünde: temelde URL'nin tamamı.
Ayrıca, doğrulayıcı http://validator.w3.org/ gibi URL'ler için geçer "你好"
ve boşluk gibi karakterlere sahip URL'ler için geçmez"a b"
Tabii ki, Stephen C tarafından belirtildiği gibi, bu sadece karakterlerle değil, aynı zamanda bağlamla da ilgilidir: tüm algoritmayı anlamalısınız. Ancak "URL kod noktaları" sınıfı algoritmanın kilit noktalarında kullanıldığından, neyi kullanabileceğiniz veya kullanamayacağınız hakkında iyi bir fikir verir.
Ayrıca bkz: URL'lerde Unicode karakterler
URL URL'leri kendim bulunamadı karakterleri listesi oluşturmaya karar verdi, bu nedenle dize URL'leri bölmek için karakter seçmek gerekir:
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
Yani, olası seçenekler satırsonu, sekme, boşluk, ters eğik çizgi ve "<>{}^|
. Sanırım boşluk veya satırsonu ile gideceğim. :)
Sorunuza gerçekten bir cevap değil, ancak URL'leri doğrulamak gerçekten ciddi bir pide Muhtemelen sadece alan adını doğrulamaktan daha iyi ve URL'nin sorgu kısmını bırakın. Bu benim deneyimim. Ayrıca, URL'ye ping atmak ve geçerli bir yanıtla sonuçlanıp sonuçlanmadığını görmek için başvurabilirsiniz, ancak bu böyle basit bir görev için çok fazla olabilir.
URL'leri tespit etmek için düzenli ifadeler bol, google :)
Eski http (0.9, 1.0, 1.1) istek ve yanıt okuyucusu / yazarı uyguluyorum. İstek URI'si en sorunlu yerdir.
RFC 1738, 2396 veya 3986'yı olduğu gibi kullanamazsınız. Daha fazla karaktere izin veren birçok eski HTTP istemcisi ve sunucusu vardır. Yaptığım Yani araştırma yanlışlıkla yayınlanan web sunucusu erişim günlükleri dayalı: "GET URI HTTP/1.0" 200
.
Aşağıdaki standart dışı karakterlerin URI'de sıklıkla kullanıldığını gördüm:
\ { } < > | ` ^ "
Bu karakterler RFC 1738'de güvensiz olarak tanımlanmıştır .
Tüm eski HTTP istemcileri ve sunucularıyla uyumlu olmak istiyorsanız - istek URI'sında bu karakterlere izin vermelisiniz .
Lütfen bu araştırma hakkında daha fazla bilgiyi http-og adresinde okuyun .
Ben PHP metin için URL'leri çapa etiketleri dönüştürecek birkaç düzenli ifadeler ile geldi. (Önce tüm www. Url'leri http: // 'ye dönüştürür, sonra https?: // içeren tüm URL'leri bir href = ... html bağlantılarına dönüştürür
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string)
);