Stroustrup a récemment publié une série de messages qui réfutent les mythes populaires sur le C ++ . Le cinquième mythe est le suivant: «C ++ s’applique uniquement aux grands programmes compliqués». Pour le démystifier, il a écrit un simple programme C ++ téléchargeant une page Web et en extrayant des liens . C'est ici:
#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;
}
}
Montrons à Stroustrup ce qu'est un petit programme lisible .
- Télécharger
http://www.stroustrup.com/C++.html
Lister tous les liens:
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 ...
Vous pouvez utiliser n'importe quelle langue, mais aucune bibliothèque tierce n'est autorisée.
Gagnant
La réponse C ++ a été remportée par un vote, mais elle repose sur une bibliothèque semi-tierce (interdite par les règles) et, avec un autre concurrent proche, Bash , sur un client HTTP piraté (cela ne fonctionnera pas avec HTTPS, gzip, redirections, etc.). Donc, Wolfram est un gagnant clair. Une autre solution qui se rapproche du point de vue de la taille et de la lisibilité est PowerShell (avec une amélioration par rapport aux commentaires), mais elle n’a pas suscité beaucoup d’attention. Les langages traditionnels ( Python , C # ) sont également très proches.
Content-Type: text/html; charset=UTF-8
... Je vais lui envoyer un courriel.boost/asio
est utilisé là - bas qui est une bibliothèque tiers. Je veux dire, comment les langues qui n'incluent pas l'extraction url / tcp dans le cadre de sa bibliothèque standard entrent-elles en concurrence?Réponses:
Wolfram
Cela ressemble à de la triche complète
Il suffit donc d'ajouter une analyse honnête sur le dessus
la source
C ++
Le principal inconvénient est la nature délicate de boost :: asio, je suis sûr que cela peut être encore plus court avec une meilleure bibliothèque.
la source
import urllib2
, C3 peut être encoreusing System.Net
, Haskel peut encoreimport Network.HTTP
, mais un codeur C ++ doit trouver des excuses pour avoir le même sens#include <boost/asio.hpp>
que s'il avait un métrique de bibliothèques C ++ (et C!) Spécialisées, spécialement conçues à cet effet. il est honteux de pouvoir choisir parmi les choix disponibles simplement parce que le comité n'a pas pris la peine de vous gaver de force ...System.Net
n'est pas forcé, c'est juste une bibliothèque de haute qualité qui respecte toutes les recommandations .NET incluses dans le langage. Il existe d’autres implémentations, mais le support HTTP dans la bibliothèque standard signifie que l’écriture d’applications simples est simple, elle permet une meilleure interopérabilité entre les bibliothèques tierces, moins de dépendances, une implémentation facile pour les façades, etc. Imaginez un monde sansstd::string
, imaginez comment tout le monde utilise leur propre bibliothèque, imaginez toutes les difficultés qui vont avec.urllib2
n'est pas une 3ème partie. C'est dans stdlib comme<iostream>
en C ++.urllib2
en Python est toujours disponible contrairement<boost/asio.hpp>
à C ++. Si nous étions autorisés à utiliser des modules tiers; Je voudrais utiliserlxml
ouBeautifulSoup
en Python.Pure Bash sous Linux / OS X (pas d'utilitaire externe)
Le logiciel client HTTP est notoirement gonflé. Nous ne voulons pas de ce genre de dépendances. Au lieu de cela, nous pouvons insérer les en-têtes appropriés dans un flux TCP et lire le résultat. Nul besoin d'appeler des utilitaires archaïques comme grep ou sed pour analyser le résultat.
Meh - Je suppose que ça pourrait être plus lisible ...
la source
mapfile
:)mapfile
vient avec bash 4.x. La même chose est tout à fait faisable avec unewhile read
boucle.while read
lieu demapfile
. Plus portable et plus lisible, je pense.Python 2
Lame, mais fonctionne
la source
l = re.findall('"((http)s?://.*?)"', u.urlopen(s).read())
urlopen()
). Que devrait-il faire d'une telle exception, à part le crash et la mort? Si cela devait se bloquer et mourir de toute façon, pourquoi ne pas simplement laisser Python gérer le crash et la mort, et laisser de côté la gestion des exceptions?urlopen
erreurs plutôt que (par exemple) les rattraper et les appelersys.exit("something's borked!")
. S'ils font ce dernier, je dois attraperSystemExit
, ce qui n'est jamais amusant.C #
la source
var html
et probablementvar match
raser quelques personnages.html
variables, mais ce n'est pas ce que je recherche.var
quand cela n'aura pas d'impact sur la sémantique du code?"Pas de tiers" est une erreur
Je pense que l'hypothèse "pas de tierce partie" est une erreur. Et est une erreur spécifique qui afflige les développeurs C ++, car il est si difficile de créer du code réutilisable en C ++. Lorsque vous développez quelque chose que ce soit, même s'il s'agit d'un petit script, vous utiliserez toujours les morceaux de code réutilisables qui vous sont disponibles.
Le fait est que, dans des langages comme Perl, Python, Ruby (pour n'en nommer que quelques-uns), la réutilisation du code de quelqu'un d'autre est non seulement facile, mais permet également à la plupart des gens d'écrire du code la plupart du temps.
C ++, avec ses exigences ABI compatibles presque impossibles à maintenir, rend ce travail beaucoup plus difficile, vous vous retrouvez avec un projet comme Boost, qui est un immense dépôt de code et une très faible composabilité en dehors de celui-ci.
Un exemple de CPAN
Juste pour le plaisir, voici un exemple basé sur CPAN, avec une analyse syntaxique correcte du html, au lieu d’ essayer d’utiliser regex pour analyser html
la source
Shell UNIX
Trouve également un
ftp://
lien :)Une autre façon, sans compter sur la
://
syntaxe:la source
lynx
correspond fonctionnellement à une bibliothèque tierce dans ce scénario.CSS 3
Ce code peut être utilisé comme style utilisateur pour afficher uniquement les liens absolus sur une page dans une liste non formatée. Il risque de ne pas fonctionner correctement si votre navigateur impose une taille de police minimale.
Cela fonctionne correctement avec
http://www.stroustrup.com/C++.html
(note!important
surbackground
). Pour pouvoir travailler sur d'autres pages avec plus de styles, il doit être étendu (réinitialiser davantage de propriétés, marquer les propriétés comme importantes, etc.).Version alternative qui inclut des liens relatifs sauf les liens intrapage commençant par des hachages (elle repose malheureusement sur un lien absolu codé en dur):
la source
Clojure
la source
spit
,zipper
etlazy-cat
... :-)Emacs Lisp
la source
Scala
la source
ftp://ftp.research.att.com/pub/c++std/WP/CD2
?PHP 5
la source
'/"((http)s?://.*?)"/'
⇒'|"((http)s?://.*?)"|'
(actuellement une erreur); removearray_unshift($m);
(actuellement une erreur, vous vouliez probablement dire à laarray_shift
place);print_r($m);
⇒print_r($m[1]);
(ne sortir que les URL).PowerShell
Recherche de texte pour toutes les URL entièrement qualifiées (y compris JavaScript, CSS, etc.):
Ou pour obtenir des liens dans les balises d'ancrage uniquement (inclut les URL relatives):
Des versions plus courtes des commentaires:
la source
iwr
est un alias pourInvoke-WebRequest
(PS3 +).(iwr "http://www.stroustrup.com/C++.html").Links.href
(ou(iwr "http://www.stroustrup.com/C++.html").Links.href-match":"
uniquement pour lesré
la source
| sort | uniq
ou au lieu d' ajouterimport std.array
et de modifier la ligne.filter!("a")){ writeln(_.front[1]); }
dans ce:.filter!("a").map!(a => a.front[1]).array.sort.uniq){ writeln(_); }
. Notez, cependant, que j'ai seulement essayé ce code et que je n'ai pas prouvé qu'il était correct ou "idiomatique". :)Node.js
la source
require('http').get
marche. Si c'est le cas, nous pouvons abandonner l'instruction var et raccourcir une autre ligne.Rubis
la source
%r{"(https?://[^"]+)"}
. Vous pouvez également utiliserNet::HTTP.get('www.stroustrup.com', '/C++.html')
pour raccourcir la demande (et la garder lisible). Ainsi , le code entier peut être dans une ligne (garder lisible):puts Net::HTTP.get("www.stroustrup.com", "/C++.html").scan(%r{"(https?://[^"]+)"})
. Exécutez-le avecruby -rnet/http
et vous n'avez même pas besoin derequire 'net/http'
ligne.Haskell
Quelques problèmes avec
"\w"
dans Text.Regex.Posixla source
result
spécifié explicitement? Il devrait être entièrement contraint par son utilisation dansunlines
.Network.HTTP
niTextRegex.Posix
dans l'base
emballage. (Bien qu'ils soient dans la plate-forme Haskell, et bien sûr sur Hackage, alors ...)network
est pasbase
non plus , donc économiser pour rouler vos propres liaisons socket il n'y a aucun moyen pratique de le faire avec justebase
.PHP
Autant que je sache, la plupart des installations PHP modernes intègrent un traitement DOM. En voici donc une qui traverse les ancres à l'intérieur du code HTML:
La boucle interne pourrait être réduite à:
la source
1
au lieu de latrue
pour lain_array
recherche stricte. Vous pouvez également omettre les crochets. Je ne suis pas tout à fait sûr, mais vous pourriez aussi bien laisser tomber le boutonhttp
et le laisser://
(ne pas utiliser le système). .if ( ) {}
en faveur dein_array() and print $url.PHP_EOL
. Mais oui, vous auriez un autre +1 (si je pouvais) pour une meilleure lisibilité :)@\DOMDocument
. Je viens d’essayer ça et je peux confirmer que ça marche.::loadHTMLFile()
statiquement et ajouter@
uniquement les peaux à cet artefact.Unix Shell
Bien que je dois admettre que cela ne fonctionne pas s'il y a plus d'un lien sur une ligne.
la source
curl http://www.stroustrup.com/C++.html
enregistre quelques caractères.wget
GNU (comme Bash) est bas, vous pourriez dire que ce n’est pas une tierce partie. Maiscurl
est définitivement tiers.ftp://ftp.research.att.com/pub/c++std/WP/CD2
ethttps://www.youtube.com/watch?v=jDqQudbtuqo&feature=youtu.be
?Java
la source
Scanner
vous pouvez lui demander de traiter directement le motif de regex pour les liens et de parcourir lesScanner
résultats.Sensationnel
la source
SQL (SQL Anywhere 16)
Définir une procédure stockée pour récupérer la page Web
Produire le jeu de résultats en utilisant une seule requête
Limitations: Cela produit jusqu'à 256 liens. Si plus de liens existent, alors remplacez le 256 par une valeur appropriée.
la source
CoffeeScript / NodeJS
la source
Perl
la source
use v5.10;
etsay for $response->content
...say
sont très utiles et, à mon avis, plus claires ici. (En outre, perl5 a connu de nombreuses améliorations au cours des 13 dernières années; elles mériteraient sans doute d'être vérifiées.)say
c'est probablement plus lisible dans ce cas, en particulier pour ceux qui sont moins familiers avec perl.R
... bien que R soit écrit principalement en C ... donc probablement quelques lignes de code C derrière ces 2 lignes de code R.
la source
Objectif c
la source
Tcl
la source
[
. Mais c'est un choix de style.Aller
PS: ce code lit l'intégralité de la source en mémoire, pensez donc à utiliser la
regexp.FindReaderIndex
recherche en flux pour rendre l'application à l'épreuve des balles.la source
CJam
CJam n'a pas de regex et j'ai donc dû utiliser une approche différente dans celle-ci:
Je convertis d'abord tout
'
en"
, puis je divise tout"
, je prends chaque chaîne alternative et enfin filtre cette liste pour les chaînes commençant parhttp://
ouhttps://
. Ensuite, imprimez simplement chaque chaîne filtrée sur une nouvelle ligne.Essayez-le en utilisant l' interpréteur Java comme
où fichier.cjam a le contenu du code ci-dessus.
la source
''/'"f/:+
pour''/'"*'"/'"f/0f=
.'"f/0f=
il? Est-ce censé faire quelque chose (2%
par exemple)?F#
Ce code pourrait être beaucoup plus court, mais j'écrirais quelque chose comme ceci si je m'attendais à devoir lire ou utiliser à nouveau ce code afin qu'il contienne de nombreuses annotations de type inutiles. Il illustre l'utilisation d'un modèle actif MatchValue pour permettre la correspondance de modèle avec le type de CLR standard Match
Edit j'ai fait à getLinks sa propre fonction
la source