F # подсчет символов и гиперссылок в импортированных строках URL - PullRequest
0 голосов
/ 01 декабря 2018

У меня проблема с подсчетом количества <a ... </a> гиперссылок / тегов в импортированной строке URL-адреса с любого веб-сайта.А также подсчет количества появлений символов в одной строке.Последнее, кажется, работает, с моим кодом на данный момент:

let countChars (url:string) (tag: 'a) =
    let link = fetchUrl (url)
    let rec loop i count =
        if i < link.Length then
            if (link.[i] = tag) then loop (i+1) (count+1)
            else loop (i+1) count
        else count
    loop 0 0

Я использую следующее для определения моей функции fetchUrl:

let fetchUrl (url:string) : string =
    let req = WebRequest.Create(Uri(url))
    use resp = req.GetResponse()
    use stream = resp.GetResponseStream()
    use reader = new IO.StreamReader(stream)
    in reader.ReadToEnd()

Однако я застрял в настоящее время, так как яУ меня проблема с выяснением, как именно я буду рассчитывать теги в импортированной строке URL.В моем примере здесь я зацикливаюсь на строке url, считая только появление символа, такого как 'a', но я не могу найти способ применить это к моему решению, где в качестве подстроки я на самом деле ищуявляется выражением нескольких символов, содержащим выражения <a ... </a>.

У меня есть другое решение, которое реализует регулярные выражения, чтобы попытаться справиться с фактическим выражением тега, которое я ищу.Этот код выполняется, но возвращаемое значение является ненормальным:

let countTags (url:string) (tag:string) =
    let link = fetchUrl (url)
    let m = Regex.Match(link,tag)
    let rec loop i count =
        if i < link.Length then
            if m.Success then loop (i+1) (count+1)
            else loop (i+1) count
        else count
    loop 0 0

Результаты, полученные при вызове этой функции со следующим, показаны справа.

printfn "%A" (countTags "https://forum.astronomisk.dk/" "(?s)<a [^>]*?>(?<text>.*?)</a>") --> result: 75640

printfn "%A" (countTags "https://www.ku.dk/" "(?s)<a [^>]*?>(?<text>.*?)</a>") --> result: 57459

printfn "%A" (countTags "https://www.google.com/" "(?s)<a [^>]*?>(?<text>.*?)</a>") --> result: 47120

Результаты соответствуютк моему определению «сумасшедший» (учитывая, что ссылки в этом случае возвращают около 47-75k <a href=....</a> тегов для 3 простых импортированных строк url).Вызов первой функции для импортированной строки url с теми же тестами, только с поиском char 'a', дает результат около 2500-3000, что, по моим оценкам, вполне разумно и, кажется, работает нормально.

Может кто-нибудьвидите, чего мне здесь не хватает?Является ли моя реализация регулярного выражения неправильной, поскольку она возвращает такой высокий результат?Или есть какой-то другой способ подсчета количества тегов <a ... </a> в любой заданной импортированной строке URL-адреса.Я пытался найти решение весь день, не имея возможности окончательно закрыть проект с удачным кодом.

Любая помощь в исправлении того, что я остаюсь, ценится!

1 Ответ

0 голосов
/ 01 декабря 2018

Ваша первая проблема заключается в том, что countTags, кажется, считает длину документа, который вы просматриваете (если документ содержит тег привязки).

Причина этого в том, что Regex.Match ищет first совпадение, следовательно, m.Success всегда верно.

То, что вы хотите, это Regex.Matches.Это дает вам MatchCollection, для которого вы можете взять ´.Count´.

Также взгляните на this для регулярного выражения, соответствующего тегам привязки.

Toуточнить, можно сделать

let countTags (url:string) (tag:string) =
    let link = fetchUrl url
    let regex = Regex tag
    regex.Matches(link).Count
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...