Stroustrup baru-baru ini memposting serangkaian postingan yang menghilangkan mitos populer tentang C ++ . Mitos kelima adalah: "C ++ hanya untuk program yang besar, rumit,". Untuk menghilangkan prasangka itu, ia menulis sebuah program C ++ sederhana yang mengunduh halaman web dan mengekstraksi tautan darinya . Ini dia:
#include <string>
#include <set>
#include <iostream>
#include <sstream>
#include <regex>
#include <boost/asio.hpp>
using namespace std;
set<string> get_strings(istream& is, regex pat)
{
set<string> res;
smatch m;
for (string s; getline(is, s);) // read a line
if (regex_search(s, m, pat))
res.insert(m[0]); // save match in set
return res;
}
void connect_to_file(iostream& s, const string& server, const string& file)
// open a connection to server and open an attach file to s
// skip headers
{
if (!s)
throw runtime_error{ "can't connect\n" };
// Request to read the file from the server:
s << "GET " << "http://" + server + "/" + file << " HTTP/1.0\r\n";
s << "Host: " << server << "\r\n";
s << "Accept: */*\r\n";
s << "Connection: close\r\n\r\n";
// Check that the response is OK:
string http_version;
unsigned int status_code;
s >> http_version >> status_code;
string status_message;
getline(s, status_message);
if (!s || http_version.substr(0, 5) != "HTTP/")
throw runtime_error{ "Invalid response\n" };
if (status_code != 200)
throw runtime_error{ "Response returned with status code" };
// Discard the response headers, which are terminated by a blank line:
string header;
while (getline(s, header) && header != "\r")
;
}
int main()
{
try {
string server = "www.stroustrup.com";
boost::asio::ip::tcp::iostream s{ server, "http" }; // make a connection
connect_to_file(s, server, "C++.html"); // check and open file
regex pat{ R"((http://)?www([./#\+-]\w*)+)" }; // URL
for (auto x : get_strings(s, pat)) // look for URLs
cout << x << '\n';
}
catch (std::exception& e) {
std::cout << "Exception: " << e.what() << "\n";
return 1;
}
}
Mari kita tunjukkan pada Stroustrup apa program kecil dan mudah dibaca itu sebenarnya.
- Unduh
http://www.stroustrup.com/C++.html
Daftar semua tautan:
http://www-h.eng.cam.ac.uk/help/tpl/languages/C++.html http://www.accu.org http://www.artima.co/cppsource http://www.boost.org ...
Anda dapat menggunakan bahasa apa pun, tetapi tidak ada perpustakaan pihak ketiga yang diizinkan.
Pemenang
Jawaban C ++ dimenangkan oleh suara, tetapi bergantung pada pustaka pihak ketiga (yang tidak diizinkan oleh aturan), dan, bersama dengan pesaing dekat lainnya Bash , bergantung pada klien HTTP yang diretas bersama (tidak akan bekerja dengan HTTPS, gzip, arahan ulang dll). Jadi Wolfram adalah pemenang yang jelas. Solusi lain yang mendekati dalam hal ukuran dan keterbacaan adalah PowerShell (dengan peningkatan dari komentar), tetapi belum mendapat banyak perhatian. Bahasa arus utama ( Python , C # ) juga cukup dekat.
Content-Type: text/html; charset=UTF-8
... Saya akan mengirim email kepadanya.boost/asio
digunakan di sana yang merupakan perpustakaan pihak ketiga. Maksud saya, bagaimana bahasa yang tidak menyertakan url / tcp fetching sebagai bagian dari perpustakaan standarnya akan bersaing?Jawaban:
Wolfram
Ini terasa seperti selingkuh total
Jadi, tambahkan saja penguraian jujur di atas
sumber
C ++
Kelemahan utama adalah sifat canggung boost :: asio, saya yakin bisa lebih pendek dengan perpustakaan yang lebih baik.
sumber
import urllib2
, C3 mungkin masihusing System.Net
, Haskel mungkin masihimport Network.HTTP
, tetapi seorang pembuat kode C ++ harus membuat alasan#include <boost/asio.hpp>
seolah-olah memiliki metrik crapton dari perpustakaan khusus C ++ (dan C!) Yang dibuat khusus tersedia untuk dipilih adalah sesuatu yang memalukan hanya karena panitia tidak repot-repot memberi Anda makan satu ...System.Net
tidak dipaksakan, itu hanya perpustakaan berkualitas tinggi yang mengikuti semua. Rekomendasi NET yang disertakan dengan bahasa. Sudah ada implementasi alternatif, tetapi memiliki dukungan HTTP di perpustakaan standar berarti menulis aplikasi sederhana adalah sederhana, berarti interoperabilitas yang lebih baik antara perpustakaan pihak ketiga, berarti lebih sedikit ketergantungan, berarti implementasi yang mudah untuk fasad dll. Bayangkan dunia tanpastd::string
, bayangkan bagaimana semua orang menggunakan perpustakaan mereka sendiri, bayangkan semua kesulitan yang menyertainya.urllib2
adalah tidak pihak ke-3. Ini di stdlib seperti<iostream>
di C ++.urllib2
di Python selalu tersedia tidak seperti<boost/asio.hpp>
di C ++. Jika kami diizinkan menggunakan modul pihak ke-3; Saya akan menggunakanlxml
atauBeautifulSoup
dengan Python.Pure Bash di Linux / OS X (tidak ada utilitas eksternal)
Perangkat lunak klien HTTP terkenal membengkak. Kami tidak menginginkan ketergantungan seperti itu. Sebagai gantinya, kami dapat menekan tajuk yang sesuai ke aliran TCP dan membaca hasilnya. Tidak perlu memanggil utilitas kuno seperti grep atau sed untuk menguraikan hasilnya.
Meh - Saya kira itu bisa lebih mudah dibaca ...
sumber
mapfile
:)mapfile
hadir dengan bash 4.x. Hal yang sama juga bisa dilakukan denganwhile read
loop.while read
bukanmapfile
. Lebih portabel dan lebih mudah dibaca, saya pikir.Python 2
Lumpuh, tapi berhasil
sumber
l = re.findall('"((http)s?://.*?)"', u.urlopen(s).read())
urlopen()
). Apa yang harus dilakukan dengan pengecualian seperti itu, selain crash dan mati? Jika itu akan crash dan mati, mengapa tidak membiarkan Python yang menangani crash-dan-sekarat, dan meninggalkan penanganan pengecualian sama sekali?urlopen
kesalahan daripada (katakanlah) menangkap mereka dan meneleponsys.exit("something's borked!")
. Jika mereka melakukan yang terakhir, saya harus menangkapSystemExit
, yang tidak pernah menyenangkan.C #
sumber
var html
, dan mungkinvar match
untuk memangkas beberapa karakter.html
variabel sama sekali, tapi bukan itu yang saya cari.var
ketika tidak akan memengaruhi kode semantik?"Tidak ada pihak ketiga" adalah kekeliruan
Saya pikir asumsi "tidak ada pihak ketiga" adalah kesalahan. Dan merupakan kesalahan spesifik yang menimpa pengembang C ++, karena sangat sulit untuk membuat kode yang dapat digunakan kembali dalam C ++. Ketika Anda sedang mengembangkan apa pun, bahkan jika itu adalah skrip kecil, Anda akan selalu memanfaatkan potongan kode apa pun yang dapat digunakan kembali yang tersedia untuk Anda.
Masalahnya adalah, dalam bahasa seperti Perl, Python, Ruby (untuk beberapa nama), menggunakan kembali kode orang lain tidak hanya mudah, tetapi itu adalah bagaimana kebanyakan orang benar-benar menulis kode sebagian besar waktu.
C ++, dengan hampir tidak mungkin untuk mempertahankan yang kompatibel-ABI-persyaratan membuat pekerjaan yang lebih sulit, Anda berakhir dengan proyek seperti Boost, yang merupakan repositori kode yang mengerikan dan sangat sedikit kompabilitas di luarnya.
Contoh CPAN
Hanya untuk bersenang-senang, ini contoh berbasis CPAN, dengan penguraian html yang tepat, alih-alih mencoba menggunakan regex untuk mengurai html
sumber
UNIX shell
Juga menemukan
ftp://
tautan :)Cara lain, tanpa mengandalkan
://
sintaks:sumber
lynx
secara fungsional setara dengan perpustakaan pihak ketiga dalam skenario ini.CSS 3
Kode ini dapat digunakan sebagai gaya pengguna untuk hanya menampilkan tautan absolut pada halaman dalam daftar yang tidak diformat. Ini mungkin tidak berfungsi dengan benar jika browser Anda memberlakukan ukuran font minimum.
Ini berfungsi dengan baik
http://www.stroustrup.com/C++.html
(catatan!important
aktifbackground
). Agar dapat bekerja di halaman lain dengan gaya yang lebih banyak, itu harus diperluas (reset lebih banyak properti, tandai properti sebagai penting, dll.).Versi alternatif yang mencakup tautan relatif kecuali tautan intrapage dimulai dengan hash (sayangnya, ini bergantung pada tautan absolut yang dikodekan dengan keras):
sumber
Clojure
sumber
spit
,zipper
danlazy-cat
... :-)Emacs Lisp
sumber
Scala
sumber
ftp://ftp.research.att.com/pub/c++std/WP/CD2
?PHP 5
sumber
'/"((http)s?://.*?)"/'
⇒'|"((http)s?://.*?)"|'
(saat ini merupakan kesalahan); hapusarray_unshift($m);
(saat ini merupakan kesalahan, yang mungkin Anda maksudkan adalaharray_shift
);print_r($m);
⇒print_r($m[1]);
(hanya menampilkan url).PowerShell
Pencarian teks untuk semua URL yang sepenuhnya memenuhi syarat (termasuk JavaScript, CSS, dll.):
Atau untuk mendapatkan tautan di tag jangkar saja (termasuk URL relatif):
Versi lebih pendek dari komentar:
sumber
iwr
adalah alias untukInvoke-WebRequest
(PS3 +).(iwr "http://www.stroustrup.com/C++.html").Links.href
(atau(iwr "http://www.stroustrup.com/C++.html").Links.href-match":"
hanya untuk URI absolut)D
sumber
| sort | uniq
atau sebaliknya menambahimport std.array
dan mengubah baris.filter!("a")){ writeln(_.front[1]); }
ke ini:.filter!("a").map!(a => a.front[1]).array.sort.uniq){ writeln(_); }
. Namun, perhatikan bahwa saya hanya mencoba kode ini dan tidak membuktikannya benar atau "idiomatik". :)Node.js
sumber
require('http').get
berhasil. Jika ya maka kita bisa menghilangkan pernyataan var dan mempersingkat baris lain.Rubi
sumber
%r{"(https?://[^"]+)"}
. Anda juga dapat menggunakanNet::HTTP.get('www.stroustrup.com', '/C++.html')
untuk mempersingkat permintaan (dan membuatnya mudah dibaca). Jadi seluruh kode bisa dalam satu baris (menjaga dibaca):puts Net::HTTP.get("www.stroustrup.com", "/C++.html").scan(%r{"(https?://[^"]+)"})
. Jalankan denganruby -rnet/http
dan Anda bahkan tidak perlurequire 'net/http'
garis.Haskell
Beberapa masalah dengan
"\w"
di Text.Regex.Posixsumber
result
ditentukan secara eksplisit? Itu harus sepenuhnya dibatasi oleh penggunaannya diunlines
.Network.HTTP
jugaTextRegex.Posix
berada dibase
paket. (Meskipun mereka berada di Platform Haskell, dan tentu saja di Hackage, jadi ...)network
tidak ada dibase
keduanya, jadi simpan untuk menggulung binding socket Anda sendiri tidak ada cara praktis untuk melakukannya hanya denganbase
.PHP
Sejauh yang saya tahu, sebagian besar instalasi PHP modern datang dengan pemrosesan DOM, jadi inilah salah satu yang sebenarnya melintasi jangkar di dalam HTML:
Lingkaran dalam dapat disingkat menjadi:
sumber
1
alih-alihtrue
untukin_array
pencarian ketat. Anda juga bisa menghilangkan tanda kurung. Saya tidak sepenuhnya yakin, tetapi jika Anda bisa juga drophttp
dan hanya meninggalkan://
(pergi w / o skema). .if ( ) {}
dukunganin_array() and print $url.PHP_EOL
. Tapi ya, Anda akan mendapatkan +1 lagi (jika saya bisa) untuk keterbacaan terbaik :)@\DOMDocument
. Baru saja mencobanya dan dapat mengonfirmasi itu berfungsi.::loadHTMLFile()
secara statis, dan menambahkan@
hanya menyembunyikan artefak itu.Unix Shell
Meskipun saya harus mengakui ini tidak berfungsi jika ada lebih dari satu tautan pada satu baris.
sumber
curl http://www.stroustrup.com/C++.html
menyimpan beberapa karakter.wget
itu GNU (seperti halnya bash), Anda bisa berargumen bahwa itu bukan pihak ketiga. Tapi yangcurl
pasti pihak ketiga.ftp://ftp.research.att.com/pub/c++std/WP/CD2
danhttps://www.youtube.com/watch?v=jDqQudbtuqo&feature=youtu.be
?Jawa
sumber
Scanner
Anda dapat membuatnya memproses pola regex untuk tautan secara langsung dan beralih padaScanner
hasil.Asyik
sumber
SQL (SQL Anywhere 16)
Tetapkan prosedur tersimpan untuk mengambil halaman web
Menghasilkan set hasil menggunakan satu permintaan
Keterbatasan: Ini menghasilkan hingga 256 tautan. Jika ada lebih banyak tautan, maka tambah 256 ke nilai yang sesuai.
sumber
CoffeeScript / NodeJS
sumber
Perl
sumber
use v5.10;
dansay for $response->content
...say
cukup berguna, dan dalam benak saya lebih jelas di sini. (Juga, ada banyak perbaikan perl6isme yang sama sekali tidak berhubungan dengan perl5 dalam 13 tahun terakhir; mungkin perlu dicoba.)say
mungkin lebih mudah dibaca dalam kasus ini, terutama bagi mereka yang kurang terbiasa dengan perl.R
... walaupun R ditulis terutama dalam C ... jadi mungkin beberapa baris kode C di belakang 2 baris kode R itu.
sumber
Objektif-C
sumber
Tcl
sumber
[
. Tapi itu pilihan gaya.Pergi
PS kode ini membaca seluruh sumber ke dalam memori, jadi coba gunakan
regexp.FindReaderIndex
untuk mencari dalam aliran, yang akan membuat aplikasi antipeluru.sumber
CJam
CJam tidak memiliki regex jadi saya harus menggunakan pendekatan yang berbeda dalam hal ini:
Saya pertama-tama mengonversi semua
'
menjadi"
, lalu saya membagi semua"
, mengambil setiap string alternatif dan akhirnya memfilter daftar itu untuk string yang dimulai denganhttp://
atauhttps://
. Setelah itu, cukup cetak setiap string yang difilter pada baris baru.Cobalah menggunakan juru bahasa Java seperti
di mana file.cjam memiliki isi kode di atas.
sumber
''/'"f/:+
untuk''/'"*'"/'"f/0f=
.'"f/0f=
ada? Apakah itu seharusnya melakukan sesuatu (2%
misalnya)?F #
Kode ini bisa jadi jauh lebih pendek tetapi saya akan menulis sesuatu seperti ini jika saya pernah berharap harus membaca atau menggunakan kode ini lagi sehingga memiliki banyak anotasi jenis yang tidak perlu. Ini menunjukkan penggunaan pola aktif matchValue untuk memungkinkan pencocokan pola terhadap tipe standar CLR Pertandingan
Sunting Saya menjadikan getLinks fungsinya sendiri
sumber