Debunking การ debunking ของ Stroustrup ในตำนาน“ C ++ สำหรับโปรแกรมขนาดใหญ่ซับซ้อนเท่านั้น”


161

Stroustrupได้โพสต์เมื่อเร็ว ๆ นี้ชุดของการโพสต์ debunking ตำนานยอดนิยมเกี่ยวกับ C ++ ตำนานที่ห้าคือ:“ C ++ สำหรับโปรแกรมขนาดใหญ่ซับซ้อนเท่านั้น” เพื่อทำการ debunk มันเขาเขียนโปรแกรม C ++ ที่ง่าย ๆ ในการดาวน์โหลดเว็บเพจและแยกลิงค์ออกมา นี่มันคือ:

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

มาแสดง Stroustrup ว่าโปรแกรมขนาดเล็กและอ่านง่ายคืออะไร

  1. ดาวน์โหลด http://www.stroustrup.com/C++.html
  2. แสดงรายการลิงก์ทั้งหมด:

    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
    ...
    

คุณสามารถใช้ภาษาใดก็ได้ แต่ไม่อนุญาตให้ใช้ห้องสมุดบุคคลที่สาม

ผู้ชนะ

คำตอบ C ++ชนะโดยการโหวต แต่ขึ้นอยู่กับห้องสมุดกึ่งบุคคลที่สาม (ซึ่งไม่ได้รับอนุญาตตามกฎ) และพร้อมกับคู่แข่งที่ใกล้ชิดคนอื่น ๆทุบตีอาศัย HTTP ที่ถูกแฮ็กเข้าด้วยกันไคลเอนต์ HTTP (จะไม่ทำงานกับ HTTPS) gzip, การเปลี่ยนเส้นทางเป็นต้น) ดังนั้นWolframจึงเป็นผู้ชนะที่ชัดเจน อีกวิธีที่ใกล้เคียงกับขนาดและความสามารถในการอ่านคือPowerShell (พร้อมการปรับปรุงจากความคิดเห็น) แต่ก็ไม่ได้รับความสนใจมากนัก ภาษาหลัก ( Python , C # ) ก็เข้ามาใกล้เช่นกัน


43
สำหรับตัวเขาแต่ละตัวฉันถูกเรียกว่าแย่ลง หากเป้าหมายของ OP ไม่ได้ลองและพิสูจน์ว่า Stroustrup ผิดฉันก็เห็นด้วยกับการประเมินของคุณ แต่หลักฐานทั้งหมดของคำถามคือการแสดงให้เห็นว่า "ภาษาที่คุณโปรดปราน" สามารถทำสิ่งเดียวกันกับ C ++ 50 บรรทัดในรหัสบรรทัดที่น้อยกว่านี้มาก ปัญหาคือไม่มีตัวอย่างใดที่ทำสิ่งเดียวกัน โดยเฉพาะอย่างยิ่งไม่มีคำตอบใดที่ดำเนินการตรวจสอบข้อผิดพลาด แต่ไม่มีคำตอบใดที่ให้ฟังก์ชั่นที่นำกลับมาใช้ใหม่ได้คำตอบส่วนใหญ่ไม่ได้จัดให้มีโปรแกรมที่สมบูรณ์ ตัวอย่าง Stroustrup จัดเตรียมทั้งหมด
Dunk

19
มีอะไรน่าเศร้าก็คือหน้าเว็บของเขาไม่ถูกต้องแม้ UTF-8 ตอนนี้ฉันต้องแก้ไขเรื่องนี้แม้ว่าจะมีโฆษณาเซิร์ฟเวอร์ของเขาContent-Type: text/html; charset=UTF-8... ฉันจะส่งอีเมลถึงเขา
Cornstalks

27
@Dunk ตัวอย่างอื่น ๆ ไม่ได้มีฟังก์ชั่นที่ใช้ซ้ำได้เพราะพวกเขาบรรลุฟังก์ชั่นทั้งหมดของฟังก์ชั่นเหล่านั้นในบรรทัดเดียวและมันไม่มีเหตุผลที่จะทำให้ฟังก์ชั่นทั้งหมดด้วยตัวเองและตัวอย่าง C ++ ไม่ทำการตรวจสอบข้อผิดพลาดใด ๆ ที่ไม่ได้รับการจัดการในลักษณะที่เกือบเหมือนกันและวลี "โปรแกรมที่สมบูรณ์" เกือบไร้ความหมาย
Jason

16
"คุณสามารถใช้ภาษาใดก็ได้ แต่ไม่อนุญาตให้ใช้ห้องสมุดบุคคลที่สาม" ฉันไม่คิดว่าการพิจารณาความต้องการที่เป็นธรรมboost/asioนั้นจะใช้หมดไปซึ่งเป็นห้องสมุดบุคคลที่สาม ฉันหมายถึงภาษาที่จะไม่รวมการดึงข้อมูล url / tcp เป็นส่วนหนึ่งของห้องสมุดมาตรฐานจะแข่งขันกันอย่างไร
greatwolf

คำตอบ:


115

วุลแฟรม

รู้สึกเหมือนโกงอย่างสมบูรณ์

Import["http://www.stroustrup.com/C++.html", "Hyperlinks"]

ดังนั้นเพียงแค่เพิ่มการแยกวิเคราะห์ที่ซื่อสัตย์อยู่ด้านบน

Cases[
 Import["http://www.stroustrup.com/C++.html", "XMLObject"],
 XMLElement["a", {___, "href" -> link_, ___}, ___] :> 
  link /; StringMatchQ[link, RegularExpression["((http://)?www([./#\\+-]\\w*)+)"]]
, Infinity]

49
ไม่ฉันไม่เห็นการโกงใด ๆ ที่นี่ ความท้าทายนี้เกี่ยวกับการนำภาษาที่ดีที่สุดของคุณออกมา และบรรทัดแรกนั้นคือสิ่งที่ดีเลิศของ "เล็กและอ่านได้"
Martin Ender

คำตอบที่สามารถเพิกเฉยต่อข้อโต้แย้งโง่ ๆ เกี่ยวกับการจับลิงค์ FTP สุกใส
เซทแบตทิน

มาที่นี่เพื่อนำเสนอวิธีการแก้ปัญหานี้แน่นอนยินดีที่จะเห็นคนอื่นได้ชื่นชมมันเช่นกัน
Michael Stern

@ MartinBüttnerในกรณีนี้คุณอาจต้องการพิจารณา downvoting meta.codegolf.stackexchange.com/a/1078/12130
David Mulder เมื่อ

6
@DavidMulder ในทางเทคนิคแล้วช่องโหว่นี้ไม่ถูกต้องเนื่องจากการแบ่งการโหวตเป็น + 41 / -21 (และคำถามของช่องโหว่นั้นระบุว่าช่องโหว่นั้นได้รับการยอมรับ โทรใกล้เป็นที่ยอมรับ แต่ก็ยัง ;) นอกจากนี้เป็นการประกวดความนิยมไม่ใช่โค้ดกอล์ฟและโดยเฉพาะอย่างยิ่งมันเป็นป๊อปคอนเกี่ยวกับการแสดงว่าสิ่งนี้สามารถทำได้อย่างง่ายดายในภาษาที่กำหนดซึ่งเป็นเหตุผลที่ฉันคิดว่าช่องโหว่ไม่ได้ใช้กับ ความท้าทายนี้ต่อไป (เนื่องจากความท้าทายโดยทั่วไปจะขอให้มัน)
Martin Ender

115

C ++

#include <boost/asio.hpp>
#include <regex>
#include <iostream>
int main() {
    std::string server = "www.stroustrup.com";
    std::string request = "GET http://" + server + "/C++.html HTTP/1.0\r\nHost: " + server + "\r\n\r\n";
    boost::asio::ip::tcp::iostream s{server, "http"};
    s << request;
    std::regex pat{R"((http://)?www([./#\+-]\w*)+)"};
    std::smatch m;
    for (std::string l; getline(s, l);)
        if (std::regex_search(l, m, pat))
            std::cout << m[0] << "\n";
}

ข้อบกพร่องหลักคือลักษณะของการกระตุ้น :: asio ฉันแน่ใจว่ามันจะสั้นลงด้วยห้องสมุดที่ดีกว่า


166
ตลกว่า "ไม่มีห้องสมุดของบุคคลที่สาม" หมายความว่า Python อาจยังคงอยู่import urllib2, C3 อาจจะยังคงusing System.Net, Haskel อาจยังคงimport Network.HTTP, แต่ coder c ++ จะต้องแก้ตัว#include <boost/asio.hpp>ราวกับว่ามีการวัด crapton ของห้องสมุด C ++ (และ C!) ที่สร้างขึ้นโดยเฉพาะ พร้อมที่จะเลือกจากเป็นสิ่งที่น่าละอายของเพียงเพราะคณะกรรมการไม่ได้รำคาญที่จะบังคับให้ฟีดคุณหนึ่งโดยเฉพาะ ...
DevSolar

19
@DevSolar เกือบจะสร้างบัญชีที่สองเพื่อมอบ upvote ให้คุณอีกครั้งสำหรับความคิดเห็นนั้น
ผู้ใช้

15
@DevSolar System.Netไม่ได้ถูกบังคับมันเป็นเพียงห้องสมุดคุณภาพสูงที่ทำตามคำแนะนำ. NET ทั้งหมดที่รวมอยู่ในภาษา มีกำลังการใช้งานทางเลือก แต่มีการสนับสนุน HTTP ในห้องสมุดมาตรฐานหมายถึงการเขียนปพลิเคชันที่เรียบง่ายเป็นเรื่องง่ายหมายถึงการทำงานร่วมกันที่ดีระหว่างห้องสมุดของบุคคลที่สามหมายถึงการพึ่งพาน้อยหมายถึงการดำเนินงานที่ง่ายสำหรับอาคาร ฯลฯ ลองจินตนาการถึงโลกโดยไม่ต้องstd::stringคิดว่าทุกคนใช้ ลองนึกภาพความยากลำบากทั้งหมดที่มาพร้อมกับห้องสมุด
Athari

17
@DevSolar: urllib2คือไม่ได้บุคคลที่ 3 มันอยู่ใน stdlib เหมือน<iostream>ใน C ++ urllib2ในหลามคือมักจะใช้ได้ไม่เหมือน<boost/asio.hpp>ใน C ++ หากเราได้รับอนุญาตให้ใช้โมดูลบุคคลที่สาม; ฉันจะใช้lxmlหรือBeautifulSoupในหลาม
jfs

22
นอกจากนี้ฉันคิดว่าความคิดเห็นที่สำคัญที่สุดคือ C ++ ไม่ได้สร้างมาตรฐานให้กับไลบรารีมาตรฐานเหมือนกับภาษาอื่น ๆ แต่ก็ยังมีไลบรารี่แบบพกพาที่ใช้กันอย่างแพร่หลายสำหรับงานเดียวกันมากมายที่เป็นมาตรฐานในภาษาต่างๆ เช่น python และ libs เหล่านี้บางตัวเกือบจะเป็นมาตรฐานจริง และนี่คือผลลัพธ์ของ C ++ ที่สามารถกำหนดเป้าหมายระบบฝังตัวด้วยไบนารีขนาดเล็กและไลบรารีขนาดเล็ก
Peter Cordes

85

Pure Bash บน Linux / OS X (ไม่มียูทิลิตี้ภายนอก)

ซอฟต์แวร์ไคลเอนต์ HTTP มีการปูดอย่างฉาวโฉ่ เราไม่ต้องการการพึ่งพาเหล่านั้น แต่เราสามารถดันส่วนหัวที่เหมาะสมลงในกระแสข้อมูล TCP และอ่านผลลัพธ์ ไม่จำเป็นต้องเรียกโปรแกรมอรรถประโยชน์ที่ล้าสมัยเช่น grep หรือ sed เพื่อแยกวิเคราะห์ผลลัพธ์

domain="www.stroustrup.com"
path="C++.html"
exec 3<> /dev/tcp/$domain/80
printf "GET /$path HTTP/1.1\r\nhost: %s\r\nConnection: close\r\n\r\n" "$domain" >&3
while read -u3; do
    if [[ "$REPLY" =~ http://[^\"]* ]]; then
        printf '%s\n' "$BASH_REMATCH"
    fi
done

Meh - ฉันคิดว่ามันอ่านง่ายกว่า ...


1
เช่นนี้ใช้การจัดการไฟล์ unix สำหรับท่อ
javadba

2
ว้าวไม่เคยคิดเลยว่าเราจะทำสิ่งนี้ได้หากไม่มีสิ่งของภายนอก แม้ว่ามันจะดูเหมือนว่าทุบตีฉัน 3.2.17 ใน LFS เป็นบิตเล็ก ๆ ที่ล้าสมัยเพื่อให้ไม่สนับสนุนmapfile:)
Ruslan

@Ruslan Yep mapfileมาพร้อมกับ bash 4.x สิ่งเดียวกันสามารถทำได้โดยสิ้นเชิงกับwhile readลูปเช่นกัน
บาดเจ็บทางดิจิตอล

3
@Ruslan ฉันเปลี่ยนไปแทนwhile read mapfileฉันคิดว่าพกพามากขึ้นและอ่านง่ายขึ้น
บาดเจ็บทางดิจิตอล

1
ทำงานบน OS X ได้เช่นกัน!
Alex Cohn

65

Python 2

import urllib2 as u, re
s = "http://www.stroustrup.com/C++.html"
w = u.urlopen(s)
h = w.read()
l = re.findall('"((http)s?://.*?)"', h)
print l

อ่อนแอ แต่ใช้งานได้


9
ทำไมไม่รวมสายเหล่านั้นเข้าด้วยกัน? l = re.findall('"((http)s?://.*?)"', u.urlopen(s).read())
ชื่อปลอม

13
มันสั้น แต่ก็ไม่ได้เป็นสำนวน (จำนวนการอ่านใน Python)
jfs

24
อืม ... ถ้ารหัสทั้งหมดของฉันเพิกเฉยข้อผิดพลาดเช่นตัวอย่างแล้ว 75% ถึง 90% ของงานของฉันจะทำในทุกโครงการที่ฉันทำงานอยู่แล้ว
Dunk

20
@Dunk: สมมติว่าตัวอย่างได้รับข้อยกเว้นบางอย่าง (เช่นจากurlopen()) มันควรทำอะไรกับข้อยกเว้นเช่นนี้นอกจากความผิดพลาดและความตาย? ถ้ามันกำลังจะพังและตายแล้วทำไมไม่ปล่อยให้หลามจัดการกับความล้มเหลวและตายไปและจัดการกับข้อยกเว้นโดยสิ้นเชิง?
Kevin

8
@Dunk: ถ้าผมได้ใช้คนอื่นของรหัสหลามผมค่อนข้างมากที่พวกเขาไม่ได้จับurlopenข้อผิดพลาดกว่า (พูด) sys.exit("something's borked!")จับพวกเขาและโทร หากพวกเขาทำหลังฉันต้องจับSystemExitซึ่งไม่เคยสนุก
Kevin

55

C #

using System;
using System.Net;
using System.Text.RegularExpressions;

class Program {
    static void Main() {
        string html = new WebClient().DownloadString("http://www.stroustrup.com/C++.html");
        foreach (Match match in Regex.Matches(html, @"https?://[^""]+"))
            Console.WriteLine(match);
    }
}

4
คุณสามารถใช้var htmlและอาจvar matchโกนอักขระบางตัวออกไป
Superbest

15
@ ยอดเยี่ยมที่สุดฉันสามารถตั้งชื่อตัวละครเดี่ยวและกำจัดhtmlตัวแปรโดยสิ้นเชิงเช่นกัน แต่มันไม่ใช่สิ่งที่ฉันตามมา
Athari

6
@Superbest ไม่รหัสกอล์ฟ : D
Kroltan

5
มันช่วยให้อ่านง่ายขึ้นด้วย เคยมีเหตุผลที่จะไม่ใช้หรือไม่varเมื่อมันไม่ส่งผลกระทบต่อความหมายของรหัส?
Superbest

6
@ Superbest: "มันปรับปรุงการอ่าน" เป็นอัตนัย โดยส่วนตัวแล้วฉันคิดว่าการระบุประเภทของตัวแปรอย่างชัดเจนช่วยเพิ่มความสามารถในการอ่านได้ (โดยทั่วไปเช่นในรหัสนี้ที่นี่) ฉันไม่ต้องการที่จะอภิปรายเรื่องนี้แม้ว่า; ฉันแค่ต้องการชี้ให้เห็นว่ามีทางเลือกอื่นอยู่
Cornstalks

54

"ไม่มีบุคคลที่สาม" คือการเข้าใจผิด

ฉันคิดว่า "ไม่มีบุคคลที่สาม" เป็นข้อผิดพลาด และเป็นข้อผิดพลาดที่เฉพาะเจาะจงที่ทำให้นักพัฒนา C ++ เดือดร้อนเนื่องจากเป็นการยากที่จะสร้างรหัสที่สามารถใช้ซ้ำได้ใน C ++ เมื่อคุณพัฒนาอะไรเลยแม้ว่ามันจะเป็นสคริปต์เล็ก ๆ คุณก็จะใช้ประโยชน์จากโค้ดที่สามารถนำกลับมาใช้ใหม่ได้เสมอ

สิ่งที่เป็นในภาษาเช่น Perl, Python, Ruby (เพื่อชื่อไม่กี่) การใช้รหัสของคนอื่นไม่เพียง แต่ง่าย แต่มันเป็นวิธีที่คนส่วนใหญ่เขียนรหัสจริงเวลาส่วนใหญ่

C ++ ที่แทบจะเป็นไปไม่ได้ที่จะดูแลรักษาข้อกำหนดของ ABI ทำให้การทำงานยากขึ้นคุณจบลงด้วยโปรเจคอย่าง Boost ซึ่งเป็นที่เก็บรหัสที่ใหญ่โต

ตัวอย่าง CPAN

เพียงเพื่อความสนุกของมันนี่คือตัวอย่างที่ใช้ CPAN พร้อมกับการแยกวิเคราะห์ html ที่เหมาะสมแทนที่จะพยายามใช้ regex ในการแยกวิเคราะห์ html

#!/usr/bin/perl
use HTML::LinkExtor;
sub callback {
   my ($tag, %links) = @_;
   print map { "$_\n" } values %links
}
$p = HTML::LinkExtor->new(\&callback, "http://www.stroustrup.com/C++.html");

6
โหวตขึ้นสำหรับการพูดคุยประเด็นของบุคคลที่สาม libs แต่: อึทำให้รหัสที่นำมาใช้ใหม่ใน C ++ เป็นเรื่องง่ายเหมือนภาษาอื่น การใช้และโดยเฉพาะอย่างยิ่งการหานำมาใช้ใหม่รหัสอาจจะเป็นตาดยาก แต่สิ่งเดียวที่เป็นปัญหาอย่างจริงจังเป็นการนำรวบรวมสิ่งประดิษฐ์ แต่ที่มักจะไม่ใช่ปัญหาในการแปลภาษาเช่น Perl และอื่น ๆ
มาร์ตินบา

4
เพื่อยืดความคล้ายคลึง Boost เป็นเหมือน CPAN - เลือกและเลือก คุณไม่ได้เรียก CPAN ว่าเป็น "คลังเก็บรหัสอันมหึมา" เพียงเพราะมีหลายสิ่งในนั้นที่คุณไม่ได้ใช้?
Martin Ba

22
CPAN เป็น 'คลังเก็บของรหัสที่ผิดปกติ' โดยคำจำกัดความที่สมเหตุสมผลของคำทั้งสี่
jwg

3
@MartinBa ฉันไม่เห็นด้วยภาษา C ++ เป็นภาษาที่คอมไพล์โดยกำหนดให้ทุกไฟล์ปฏิบัติการสามารถสร้างสแต็คการอ้างอิงแบบเต็มเนื่องจากมันยากที่จะรักษาความเข้ากันได้ของ ABI อย่างจริงจังขัดขวางการใช้รหัสซ้ำได้ เพื่อที่จะสร้างไลบรารี่ที่ใช้ซ้ำได้ใน C ++ คุณจะต้องผ่านความยาวที่ยาวนานมาก ๆ เพื่อให้แน่ใจว่าคุณไม่ได้บังคับให้คุณเปลี่ยนแปลง ABI ที่เข้ากันไม่ได้ตลอดเวลา
Daniel Ruoso

6
@MartinBa เพราะต้องสร้างทั้งจักรวาลใหม่ทุกครั้งที่คุณต้องการใช้งานง่าย ๆ ไม่สามารถทนทานได้
Daniel Ruoso

47

เชลล์ UNIX

lynx -dump http://www.stroustrup.com/C++.html | grep -o '\w*://.*'

พบftp://ลิงก์ด้วย :)

อีกวิธีหนึ่งโดยไม่ต้องอาศัย://ไวยากรณ์:

lynx -dump -listonly http://www.stroustrup.com/C++.html | sed -n 's/^[ 0-9.]\+//p'

38
ฉันไม่สามารถคิดได้ว่าจะ +1 เพราะการใช้เว็บเบราว์เซอร์เพื่อดาวน์โหลดหน้าเว็บเป็นเครื่องมือที่เหมาะสมสำหรับงานหรือ -1 เพราะความท้าทายคือการเขียนโปรแกรมเพื่อทำ blahblahblah และคุณเพิ่งเรียกโปรแกรมที่จะทำ blahing
David Richerby

2
ฉันคิดว่ามันจะดีกว่าที่จะแทนที่คมด้วยขดหรือ wget พวกเขามักใช้ในการดาวน์โหลดเว็บเพจ
Pavel Strakhov

4
@PavelStrakhov ผมเลือกแมวป่าชนิดหนึ่งว่าเพราะมันสามารถถ่ายโอนข้อมูลการเชื่อมโยงโดยไม่ต้องฉันทำอะไร :) พิเศษ
Ruslan

2
@SteveJessop โดย "พิเศษ" ฉันหมายถึงการแยกวิเคราะห์จริงหรือ regexing หรืออะไรก็ตาม ด้วยคมฉันเพิ่ง grep ออกรายการลิงก์ (ซึ่ง curl และ wget ไม่แสดงรายการ) และลบหมายเลข คุณอาจคิดว่ามันเป็นการโกงหรืออะไรก็ตาม แต่ฉันคิดว่ามันสนุกที่จะ {ใช้เครื่องมือที่เกือบจะทำสิ่งที่ต้องการได้อย่างสมบูรณ์ } เพียงแค่ปรับจูนผลลัพธ์
Ruslan

7
"แต่ไม่มีห้องสมุดของบุคคลที่สามได้รับอนุญาต" ฉันยืนยันว่าlynxมีฟังก์ชั่นเทียบเท่ากับห้องสมุดบุคคลที่สามในสถานการณ์นี้
Digital Trauma

43

CSS 3

* {
  margin: 0;
  padding: 0;
}
*:not(a) {
  font: 0/0 monospace;
  color: transparent;
  background: transparent !important;
}
a {
  content: "";
}
a[href*="://"]::after {
  content: attr(href);
  float: left;
  clear: left;
  display: block;
  font: 12px monospace;
  color: black;
}

รหัสนี้สามารถใช้เป็นสไตล์ผู้ใช้เพื่อแสดงเฉพาะลิงค์แบบสัมบูรณ์บนหน้าในรายการที่ไม่ได้จัดรูปแบบ อาจทำงานไม่ถูกต้องหากเบราว์เซอร์ของคุณบังคับใช้ขนาดแบบอักษรขั้นต่ำ

มันทำงานได้อย่างถูกต้องกับhttp://www.stroustrup.com/C++.html(หมายเหตุ!importantในbackground) ในการทำงานกับเพจอื่นที่มีสไตล์มากขึ้นจะต้องมีการขยาย (รีเซ็ตคุณสมบัติเพิ่มเติมทำเครื่องหมายคุณสมบัติเป็นสิ่งสำคัญเป็นต้น)

รุ่นทางเลือกซึ่งรวมถึงลิงก์ที่เกี่ยวข้องยกเว้นลิงก์ Intrapage ที่เริ่มต้นด้วยแฮช

* {
  margin: 0;
  padding: 0;
}
*:not(a) {
  font: 0/0 monospace;
  color: transparent;
  background: transparent !important;
  float: none !important;
  width: auto !important;
  border: none !important;
}
a {
  content: "";
}
a::after {
  display: none;
}
a:not([href^="#"])::after {
  content: attr(href);
  float: left;
  clear: left;
  display: block;
  font: 12px monospace;
  color: black;
}
a:not([href*="://"])::after {
  content: "http://www.stroustrup.com/" attr(href);
}

16
นี่คือสิ่งที่แย่ที่สุดที่ฉันเคยเห็น +1
Emmett R.

1
นี่คือสิ่งที่สวยงามและน่ากลัวอย่างสมบูรณ์ +1
ricdesi

36

Clojure

(->> (slurp "http://www.stroustrup.com")
     (re-seq #"(?:http://)?www(?:[./#\+-]\w*)+"))

27
Slurp ?! ฉันต้องเรียนรู้ Clojure
11684

10
@ 11,684 - Clojure นอกจากนี้ยังมีฟังก์ชั่นมาตรฐานชื่อspit, zipperและlazy-cat... :-)
บ๊อบจาร์วิส

2
ว้าวฉันคิดว่านั่นจะเป็นการแก้ปัญหาปลายปีใหม่ @BobJarvis
11684

30

Emacs Lisp

(with-current-buffer (url-retrieve-synchronously "http://www.stroustrup.com/C++.html")
  (while (re-search-forward "https?://[^\\\"]*")
    (print (match-string 0))))

2
ฉันผิดหวังเล็กน้อยเนื่องจากรหัสนี้มีขนาดกะทัดรัดและอ่านได้ชัดเจนว่ามันไม่ได้มีการลงคะแนนมากขึ้น ทำได้ดี.
Spacemoose

28

สกาล่า

"""\"(https?://.*?)\"""".r.findAllIn(scala.io.Source.fromURL("http://www.stroustrup.com/C++.html").mkString).foreach(println)

8
แพ็คทุกอย่างในบรรทัดเดียว - C ++ สามารถทำได้ด้วย
quetzalcoatl

เกี่ยวกับftp://ftp.research.att.com/pub/c++std/WP/CD2อะไร
โทเบียส Kienzler

22
@quetzalcoatl - นี่คือหนึ่งนิพจน์ไม่ใช่แค่หนึ่งบรรทัด คุณสามารถลบตัวแบ่งบรรทัดทั้งหมดออกจากรหัส C ++ ได้ แต่นั่นไม่เหมือนกับการทำงานทั้งหมดในนิพจน์เดียว
DaoWen

4
@DaoWen: ขออภัย แต่การเริ่มต้นนิพจน์-vs-line เป็นไปอย่างโง่ เพิ่มฟังก์ชั่นและ C ++ ที่คุณสามารถทำได้เช่นกัน แต่นั่นเป็นเพียงคำถามของ libs ที่ถูกพิจารณาว่า "ได้รับ" และมี "zero code inside" ไม่เปลี่ยนความจริงที่ว่าการบรรจุลงในบรรทัดทำให้อ่านง่าย หนึ่งสามารถให้มันยังคงเป็นนิพจน์เดียวและเพียงแค่ฟอร์แมตใหม่เป็นไม่กี่บรรทัดเพื่อรับมากและหลวมไม่มีอะไรอื่นนอกจาก .. นับบรรทัด นั่นคือจุดของฉัน Silly packing - C ++ สามารถทำได้เช่นกัน หากมีคนต้องการออกจากกล่อง "บรรจุโง่" แล้วควรจัดรูปแบบรหัสสำหรับการอ่านไม่ linecount
quetzalcoatl

3
@quetzalcoatl Tobias ไม่ได้ใส่ลิงค์เพื่อให้เราติดตาม เขาถามนักเขียนของคำตอบนี้ว่าทำไมมันถึงไม่ได้ผล
JLRishe

25

PHP 5

<?php
preg_match_all('/"(https?:\/\/.*?)"/',file_get_contents('http://www.stroustrup.com/C++.html'),$m);
print_r($m[1]);

5
การแก้ไขที่แนะนำ: '/"((http)s?://.*?)"/''|"((http)s?://.*?)"|'(ปัจจุบันมีข้อผิดพลาด); ลบarray_unshift($m);(ปัจจุบันมีข้อผิดพลาดคุณน่าจะตั้งใจarray_shiftแทน); print_r($m);print_r($m[1]);(ส่งออกเฉพาะ URL)
primo

แก้ไขแล้วขอบคุณสำหรับข้อมูลของคุณ
David Xu

@DavidXu ยกเว้นว่าคุณไม่ได้แก้ไข ...
Shahar

ตอนนี้มันคงที่!
David Xu

25

PowerShell

ค้นหาข้อความสำหรับURL ที่ผ่านการรับรองทั้งหมด(รวมถึง JavaScript, CSS และอื่น ๆ ):

[string[]][regex]::Matches((iwr "http://www.stroustrup.com/C++.html"), '\w+://[^"]+')

หรือเพื่อรับลิงค์ในแท็ก anchor เท่านั้น (รวม URL ที่เกี่ยวข้อง):

(iwr "http://www.stroustrup.com/C++.html").Links | %{ $_.href }

รุ่นที่สั้นกว่าจากความคิดเห็น:

(iwr "http://www.stroustrup.com/C++.html").Links.href
(iwr "http://www.stroustrup.com/C++.html").Links.href-match":"

6
หากใครสงสัยiwrก็คือนามแฝงสำหรับInvoke-WebRequest(PS3 +)
Athari

8
คุณสามารถใช้ความกระตือรือร้นของ PowerShell ในการทำให้คอลเล็กชันแบนและทำสิ่งต่อไปนี้: (iwr "http://www.stroustrup.com/C++.html").Links.href(หรือ(iwr "http://www.stroustrup.com/C++.html").Links.href-match":"สำหรับ URI แบบสัมบูรณ์เท่านั้น)
Mathias R. Jessen

1
มันค่อนข้างมีประโยชน์!
Justin Dunlap

22

D

import std.net.curl, std.stdio;
import std.algorithm, std.regex;

void main() {
foreach(_;byLine("http://www.stroustrup.com/C++.html")
    .map!((a)=>a.matchAll(regex(`<a.*?href="(.*)"`)))
    .filter!("a")){ writeln(_.front[1]); }
}

ที่จะทำให้รายการคล้ายกับตัวอย่างเดิมคุณสามารถท่อส่งออกของโปรแกรมผ่าน| sort | uniqหรือแทนที่จะเพิ่มimport std.arrayและเปลี่ยนแปลงบรรทัดลงในนี้:.filter!("a")){ writeln(_.front[1]); } .filter!("a").map!(a => a.front[1]).array.sort.uniq){ writeln(_); }อย่างไรก็ตามโปรดทราบว่าฉันได้ลองใช้รหัสนี้แล้วเท่านั้นและไม่ได้พิสูจน์ว่ามันถูกต้องหรือ "สำนวน" :)
Frg

22

Node.js

var http = require('http');

http.get('http://www.stroustrup.com/C++.html', function (res) {
    var data = '';
    res.on('data', function (d) {
        data += d;
    }).on('end', function () {
        console.log(data.match(/"https?:\/\/.*?"/g));
    }).setEncoding('utf8');
});

3
ฉันสงสัยว่าrequire('http').getทำงานได้หรือไม่ ถ้าเป็นเช่นนั้นเราสามารถทิ้งคำสั่ง var และย่ออีกบรรทัดหนึ่ง
Unihedron

@Unihedro มันทำ
TimWolla

9
@ Unihedro มันทำ แต่นี่ไม่ใช่การแข่งขันกอล์ฟ
cPu1

คุณไม่จำเป็นต้องใช้กลุ่มการจับภาพใด ๆ
Ry-

ฉันคิดว่ามันเป็นจาวาสคริปต์มากกว่าชื่อกรอบงาน
mr5

20

ทับทิม

require 'net/http'
result = Net::HTTP.get(URI.parse('http://www.stroustrup.com/C++.html'))
result.scan(/"((http)s?://.*?)"/)

1
regex %r{"(https?://[^"]+)"}ของคุณจะล้มเหลวคุณจำเป็นต้องใช้ นอกจากนี้คุณสามารถใช้Net::HTTP.get('www.stroustrup.com', '/C++.html')เพื่อย่อคำขอ (และทำให้อ่านได้) ดังนั้นโค้ดทั้งหมดจะอยู่ในบรรทัดเดียว puts Net::HTTP.get("www.stroustrup.com", "/C++.html").scan(%r{"(https?://[^"]+)"})(ทำให้มันสามารถอ่านได้): เรียกใช้ด้วยruby -rnet/httpและคุณไม่จำเป็นต้องใช้require 'net/http'สาย
Hauleth

20

Haskell

ปัญหาบางอย่าง"\w"ในใน Text.Regex.Posix

import Network.HTTP
import Text.Regex.Posix
pattern = "((http://)?www([./#\\+-][a-zA-Z]*)+)"
site = "http://www.stroustrup.com/C++.html"

main = do
    file <- getResponseBody =<< simpleHTTP (getRequest site)
    let result = getAllTextMatches $ file =~ pattern
    putStr $ unlines result -- looks nicer

ทำไมประเภทของที่resultระบุไว้อย่างชัดเจน? มันควรจะมีข้อ จำกัด unlinesอย่างเต็มที่โดยการใช้งานใน
John Dvorak

1
สิ่งนี้ยืดกฎออกไปเล็กน้อยโดยมองว่าไม่ใช่Network.HTTPหรือTextRegex.Posixอยู่ในbaseแพ็คเกจ (แม้ว่าพวกเขาจะอยู่ในแพลตฟอร์ม Haskell และแน่นอนในเรื่องของ Hackage ดังนั้น ... )
หยุดที่จะหมุน counterclock ซึ่งเป็น

1
@ JanDvorak ฉันเริ่มเขียนเป็น ghci (บางทีฉันควรโพสต์มันไม่เปลี่ยนแปลง) แต่บันทึกย่อของคุณมีความเกี่ยวข้องขอบคุณ
vlastachu

@leftaroundabout ไม่ทราบ ดูเหมือนว่าฉันไม่สามารถทำได้ถ้าใช้แพ็คเกจพื้นฐาน
vlastachu

networkไม่ได้อยู่ในอย่างใดอย่างหนึ่งเพื่อให้ประหยัดสำหรับกลิ้งผูกซ็อกเก็ตของคุณเองไม่มีวิธีการปฏิบัติที่จะทำมันมีเพียงแค่base base
แลมบ์ดาแฟรี่

18

PHP

เท่าที่ฉันจะบอกได้การติดตั้ง PHP ที่ทันสมัยส่วนใหญ่จะมาพร้อมกับการประมวลผล DOM ดังนั้นนี่คือการติดตั้งจุดยึดภายใน HTML:

foreach (@DOMDocument::loadHTMLFile('http://stroustrup.com/C++.html')->getElementsByTagName('a') as $a) {
    if (in_array(parse_url($url = $a->getAttribute('href'), PHP_URL_SCHEME), ['http', 'https'], true)) {
        echo $url, PHP_EOL;
    }
}

วงด้านในอาจสั้นลงเป็น:

preg_match('~^https?://~', $url = $a->getAttribute('href')) && printf("%s\n", $url);

ที่จริงแล้วอยากจะคิดเรื่องนี้ขึ้น (เป็นคำตอบแรกของฉันที่นี่) คุณทำมาก่อนดังนั้นนี่คือ +1 ของคุณ (สำหรับการไม่ใช้ข้อผิดพลาด Regex ที่ง่าย)! คำแนะนำ: คุณสามารถใช้ง่อย1แทนtrueการin_arrayค้นหาอย่างเข้มงวด คุณสามารถละเว้นวงเล็บได้เช่นกัน ฉันไม่แน่ใจอย่างสมบูรณ์ แต่ iirc คุณสามารถปล่อยhttpและปล่อยให้://(ไปโดยไม่มีแผน) .
ไกเซอร์

และ: ความเป็นไปได้อีกก็จะไปวางในความโปรดปรานของif ( ) {} in_array() and print $url.PHP_EOLแต่ใช่คุณจะได้รับอีก +1 (ถ้าผม) สำหรับการอ่านที่ดีที่สุด :)
Kaiser

แค่ลองตัวอย่างของคุณและได้รับข้อผิดพลาดสำหรับมาตรฐานที่เข้มงวด (PHP 5.4) ดูเหมือนว่าในแหล่งที่มามีบางลิงก์ที่เสียหายหรือจัดรูปแบบผิดด้วยอัฒภาคที่ขาดหายไป @\DOMDocumentคุณสามารถปิดการรายงานข้อผิดพลาดโดยใช้ เพิ่งลองแล้วและสามารถยืนยันการทำงาน
ไกเซอร์

ไม่มันเป็นเอกสารที่ผิด ในทางเทคนิคคุณไม่ควรโทรหา::loadHTMLFile()แบบคงที่และเพิ่มการ@ซ่อนสิ่งประดิษฐ์เพียงอย่างเดียว
แจ็ค

2
นี่เป็นหนึ่งในโซลูชั่นที่ "ถูกต้องที่สุด" ซึ่งเป็นหนึ่งในโซลูชั่นเดียวที่ฉันสามารถเห็นได้ในการใช้งาน เป็นงานที่ดี
Jordon Biondo

14

Unix Shell

wget -q -O - http://www.stroustrup.com/C++.html | sed -n '/http:/s/.*href="\([^"]*\)".*/\1/p' | sort

แม้ว่าฉันต้องยอมรับว่ามันไม่ได้ผลหากมีลิงค์มากกว่าหนึ่งลิงก์ในหนึ่งบรรทัด


1
curl http://www.stroustrup.com/C++.htmlบันทึกตัวละครไม่กี่
l0b0

7
"แต่ไม่มีห้องสมุดของบุคคลที่สามได้รับอนุญาต" ฉันเดาว่าwgetเป็น GNU (เช่นทุบตี) คุณอาจโต้แย้งว่าไม่ใช่บุคคลที่สาม แต่curlแน่นอนเป็นบุคคลที่สาม
บาดเจ็บทางดิจิทัล

สิ่งที่เกี่ยวกับftp://ftp.research.att.com/pub/c++std/WP/CD2และhttps://www.youtube.com/watch?v=jDqQudbtuqo&feature=youtu.be?
Tobias Kienzler

4
@TobiasKienzler ฉันเดาว่าโค้ดดั้งเดิมของ Stroustrup ไม่พบพวกเขาเช่นกัน
Ruslan

14

ชวา

import java.util.regex.*;
class M{
    public static void main(String[]v)throws Throwable{
        Matcher m = Pattern.compile( "\"((http)s?://.*?)\"" )
            .matcher(
                 new Scanner(
                         new URL( "http://www.stroustrup.com/C++.html" )
                             .openStream(),
                         "UTF-8")
                     .useDelimiter("\\A")
                     .next());
        while(m.find())
            System.out.println(m.group());
    }
}

3
คุณจัดรูปแบบรหัสอย่างถูกต้องในคำตอบของคุณ? มันไม่ใช่การแข่งขันสำหรับรหัสที่อ่านได้น้อยที่สุด คุณสามารถจัดรูปแบบเพื่อหลีกเลี่ยงแถบเลื่อนแนวนอนอย่างน้อย
Athari

หากคุณใช้Scannerคุณสามารถทำให้มันประมวลผลรูปแบบ regex สำหรับลิงก์โดยตรงและวนซ้ำScannerผลการค้นหาของ
Holger

5
ใช่ .. นั่นคือจาวาสำหรับคุณ การใช้โค้ดกอล์ฟเป็นงานที่ต้องทำ
javadba

4
ไม่เคยคิดว่าฉันจะเห็นโซลูชัน java ที่สั้นกว่า C ++ จริง ๆ !
slebetman

2
การแก้ไขความคิดเห็นล่าสุดของฉัน: ฉันต้องยอมรับว่านี่เป็นรหัสที่สั้นและสะอาดที่สุดที่สามารถเขียนได้ใน Java ฉันได้ลองใช้วิธีการแยกวิเคราะห์ SAX ซึ่งอาจทำให้สั้นลงด้วย lambdas แต่หน้าเว็บไม่ใช่ XHTML และ parser ส่งข้อยกเว้น Regex เป็นวิธีเดียวที่จะไป
มิสเตอร์สมิ ธ

11

Groovy

"http://www.stroustrup.com/C++.html".toURL().text.findAll(/https?:\/\/[^"]+/).each{println it}

สามารถปรับปรุงได้โดยใช้? ผู้ประกอบการเพื่อหลีกเลี่ยง NPEs?
คริส K

2
@ChrisKaminski และเป็นคนแรก (ข้าง Bjarne) แถว ๆ นี้เพื่อตรวจสอบข้อผิดพลาด? ไม่เคย! ข้างที่: ฉันเห็นเฉพาะข้อยกเว้นที่เกี่ยวข้องกับ IO ที่นี่ คุณเห็น NPE ที่ไหน
cfrick

findAll () สามารถส่งคืน null ได้หรือไม่ หรือมันจะกลับรายการที่ว่างเปล่า? ยังใหม่กับ Groovy เล็กน้อย แก้ไข: nm ดูเหมือนว่า findAll () จะส่งคืนรายการว่าง พวก Groovy พวกนั้นฉลาดมาก :-)
Chris K

11

SQL (SQL ที่ใดก็ได้ 16)

กำหนดขั้นตอนการจัดเก็บเพื่อดึงหน้าเว็บ

CREATE OR REPLACE PROCEDURE CPPWebPage()
URL 'http://www.stroustrup.com/C++.html'
TYPE 'HTTP';

สร้างชุดผลลัพธ์โดยใช้แบบสอบถามเดียว

SELECT REGEXP_SUBSTR(Value,'"https?://[^""]+"',1,row_num) AS Link  
FROM (SELECT Value FROM CPPWebPage() WITH (Attribute LONG VARCHAR, Value LONG VARCHAR) 
      WHERE Attribute = 'Body') WebPage, 
      sa_rowgenerator( 1, 256 ) 
WHERE Link IS NOT NULL;

ข้อ จำกัด : สามารถสร้างลิงค์ได้สูงสุด 256 ลิงค์ หากมีลิงค์เพิ่มเติมให้ชน 256 กับค่าที่เหมาะสม


2
ฉันไม่เชื่อว่าจะมีการเล่นกอล์ฟใน SQL ... จนถึงตอนนี้
vaxquis

ฉันเข้าใจแล้ว ... "ลิงก์" :-)
แจ็คที่ SAP Canada

10

CoffeeScript / NodeJS

require('http').get 'http://www.stroustrup.com/C++.html', (r) ->
    dt = '';
    r.on 'data', (d) -> dt += d
    r.on 'end' , (d) -> console.log dt.match /"((http)s?:\/\/.*?)"/g

1
ฉันเดาว่านี่คือ CoffeeScript / Node ใช่ไหม ฉันเดาว่าคุณควรระบุว่า ...
John Dvorak

ว้าว. อ่านได้มาก
slebetman

@slebetman แน่นอนว่ามันมีขนาดเล็ก แต่
John Dvorak

@slebetman Yeah CoffeeScript อ่านได้ง่ายกว่า JavaScript :) ฉันดีใจที่ได้กำจัดวงเล็บปีกกาทั้งหมด} :)
RobAu

9

Perl

use LWP;
use feature 'say';

my $agent = new LWP::UserAgent();
my $response = $agent->get('http://www.stroustrup.com/C++.html');

say for $response->content =~ m<"(https?://.+?)">g;

1
รหัสจะชัดเจนยิ่งขึ้นถ้าคุณหลีกเลี่ยงตัวแปรตัวคั่นฟิลด์และตัวคั่นเร็กคอร์ดและเพิ่งทำ: print map {"$ _ \ n"} $ response-> content = ~ m <"(https?: //.+ ?) "> g;
Daniel Ruoso

@DanielRuoso เห็นด้วย
primo

หรือแม้แต่use v5.10;และsay for $response->content...
Mark Reed

ฉันคิดว่าสำหรับตัวเขาแต่ละคน คุณสมบัติบางอย่างของ perl6 ที่ backported นั้นเป็นปัญหา (การจับคู่ที่ชาญฉลาดฉันกำลังมองคุณอยู่) แต่sayมีประโยชน์มากและในใจของฉันก็ชัดเจนขึ้นที่นี่ (นอกจากนี้ยังมีการปรับปรุงที่ไม่เกี่ยวข้องกับ perl6ism เป็นจำนวนมากในช่วง 13 ปีที่ผ่านมาซึ่งอาจคุ้มค่าที่จะเช็คเอาท์)
Mark Reed

@ MarkReed ฉันยอมรับว่าsayน่าจะอ่านง่ายกว่าในกรณีนี้โดยเฉพาะอย่างยิ่งสำหรับผู้ที่ไม่คุ้นเคยกับ perl
พรีโม่

9

R

html<-paste(readLines("http://www.stroustrup.com/C++.html"),collapse="\n")
regmatches(html,gregexpr("http[^([:blank:]|\\\"|<|&|#\n\r)]+",html))

... ถึงแม้ว่า R จะเขียนเป็นภาษา C เป็นหลักดังนั้นอาจมีโค้ด C สองสามบรรทัดที่อยู่ด้านหลังโค้ด R สองบรรทัด


2
(หรือคล้ายกัน) นั้นเป็นจริงสำหรับคำตอบทั้งหมดที่นี่
JLRishe

8

Objective-C

NSString *s;
for (id m in [[NSRegularExpression regularExpressionWithPattern:@"\"((http)s?://.*?)\"" options:0 error:nil] matchesInString:(s=[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.stroustrup.com/C++.html"]])]){
    NSLog(@"%@",[s substringWithRange:[m range]]);
}

3
อะไร? กรุณาเขียนรุ่น Swift ว่าเรื่องไร้สาระวงเล็บเหลี่ยมทำร้ายดวงตาของฉัน :)
มิสเตอร์สมิ ธ

2
Hurray สำหรับ []! นอกจากนี้เราควรเพิ่มเวอร์ชัน Smalltalk โดยสิ้นเชิง;)
Bersaelor

@MisterSmith คำตอบอย่างรวดเร็วขณะนี้สามารถใช้ได้ที่นี่
JAL

7

Tcl

package require http
set html [http::data [http::geturl http://www.stroustrup.com/C++.html]]
puts [join [regexp -inline -all {(?:http://)?www(?:[./#\+-]\w*)+} $html] \n]

คุณสามารถหนีไปได้โดยการทำ http :: data ภายในเครื่อง ไม่จำเป็นต้องสร้างตัวแปรชั่วคราว [และฉันยังต้องการรูปแบบการขึ้นบรรทัดใหม่โดยการใส่และการเยื้องในทุก แต่นั่นเป็นตัวเลือกสไตล์
slebetman

7

ไป

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "regexp"
)

func main() {
    resp, err := http.Get("http://www.stroustrup.com/C++.html")
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    defer resp.Body.Close()
    data, _ := ioutil.ReadAll(resp.Body)
    results := regexp.MustCompile(`https?://[^""]+`).FindAll(data, -1)
    for _, row := range results {
        fmt.Println(string(row))
    }
}

PSรหัสนี้อ่านแหล่งที่มาทั้งหมดลงในหน่วยความจำดังนั้นให้พิจารณาใช้regexp.FindReaderIndexเพื่อค้นหาในสตรีมซึ่งจะทำให้แอปกันกระสุน


6

CJam

CJam ไม่มี regex ดังนั้นฉันต้องใช้วิธีที่แตกต่างในอันนี้:

"http://www.stroustrup.com/C++.html"g''/'"*'"/(;2%{_"http://"#!\"https://"#!e|},N*

ครั้งแรกที่ผมแปลง'ไป"แล้วฉันแยกในทุก"ใช้สตริงทุกทางเลือกและแล้วในที่สุดกรองรายชื่อที่สำหรับสตริงเริ่มต้นด้วยหรือhttp:// https://หลังจากนั้นให้พิมพ์แต่ละสตริงที่กรองในบรรทัดใหม่

ลองใช้โดยใช้ล่าม Javaเช่น

java -jar cjam-0.6.2.jar file.cjam

โดยที่ file.cjam มีเนื้อหาของรหัสด้านบน


9
ไม่ทราบเกี่ยวกับส่วนที่อ่านได้ ... ไม่รู้ว่า Cjam มีฟังก์ชั่นการใช้งานเว็บ
Def

หากคุณต้องการกอล์ฟมัน ... สำหรับ''/'"f/:+ ''/'"*'"/'"f/0f=
jimmy23013

... รอทำไมอยู่ที่'"f/0f=นั่น? ควรจะทำบางสิ่ง ( 2%เช่น)
jimmy23013

6

F #

รหัสนี้อาจสั้นกว่านี้มาก แต่ฉันจะเขียนแบบนี้ถ้าฉันคาดว่าจะต้องอ่านหรือใช้รหัสนี้อีกครั้งดังนั้นจึงมีคำอธิบายประกอบประเภทที่ไม่จำเป็นจำนวนมาก มันแสดงให้เห็นถึงการใช้รูปแบบการใช้งานMatchValueเพื่อเปิดใช้งานรูปแบบจับคู่กับมาตรฐานประเภท CLR Match

open System.Net

let (|MatchValue|) (reMatch: Match) : string = reMatch.Value

let getHtml (uri : string) : string = 
    use webClient = WebClient() in
        let html : string = webClient.DownloadString(uri)
        html

let getLinks (uri : string) : string list =
    let html : string = getHtml uri
    let matches : MatchCollection = Regex.Matches(html, @"https?://[^""]+") 
    let links = [ for MatchValue reMatch in matches do yield reMatch ]
    links

let links = getLinks "http://www.stroustrup.com/C++.html" 
for link in links do
    Console.WriteLine(link)

แก้ไข ฉันทำ getLinks ฟังก์ชั่นของตัวเอง


ฉันชอบวิธีที่คุณใช้คำอธิบายประกอบประเภท ฉันคิดว่าการตั้งชื่อค่าเพื่ออธิบายสิ่งที่คุณกลับมาก็โอเค แต่ชื่อของฟังก์ชั่นนั้นมีความหมายเพียงพอ: ค่า getHTML และ html, getLinks และค่าลิงก์ สองบรรทัดสุดท้ายอาจเป็นลิงก์ |> Seq.iter (printfn "% s")
MichalMa

@MichalMa ฉันยอมรับว่าชื่อของฟังก์ชั่นนั้นมีความหมายมากพอสำหรับตัวมันเองตัวแปร html และ links นั้นมีเหตุผลในทางปฏิบัติ: ดังนั้นจึงมีบางที่ที่จะตั้งเบรกพอยต์ ฉันใช้ for for loop แทน List.iter เพียงเพราะฉันชอบวิธีที่อ่านเพิ่มขึ้นแม้ว่าใน repl ฉันอาจจะใช้ List.iter
SourceSimian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.