最优雅的方法来解析OCaml中的IP地址

时间:2015-05-09 19:02:51

标签: string parsing ocaml

我正在编写一个查询http://checkip.dyndns.org/以获取用户IP地址的工具。我需要解析将以

形式返回的结果
<html><head><title>Current IP Check</title></head><body>Current IP Address: 128.237.138.116</body></html>

我可以通过重复调用int_of_string来做一些尴尬的事情,但我想有一个很好的,简洁的方法用正则表达式或类似的东西来做这个吗?例如某种形式

let ip_re = Str.regexp ".*Address: %d.%d.%d.%d". 

或许这最好用scanf完成?对于惯用语OCaml有更多了解的人能指出正确的方法吗?

3 个答案:

答案 0 :(得分:2)

你没有说出你真正想做的事情。由于答案来自中等可靠的来源,假设您只想提取IP地址。换句话说,你想要在提取一个你几乎可以确定的IP地址的同时容忍格式的微小变化。

对于你给出的价值,我倾向于做这样的事情:

let extract_ip s =
    let nums = Str.split (Str.regexp "[^0-9]+") s in
    String.concat "." nums

如果您想要更加小心,可以验证列表中有4个数字。为了更加小心,您可以验证每个数字在0到255之间(包括)。

如果Dyndns在页面中引入了不属于IP地址的任何数字,则会失败。 (像<h1>这样的东西,更复杂的标签文本等等。)你可以通过让这段代码变得更聪明来回应(例如,拿你在页面上看到的最后 4个数字) 。或者您可以放弃并实际开始解析HTML。我的建议:不要尝试使用正则表达式,使用真正的HTML解析器。

答案 1 :(得分:1)

不需要正则表达式。

这是一个自包含的示例,它应该使用utop运行并依赖于ezxmlm,您可以使用opam install ezxmlm安装

#require "ezxmlm, str"

let example = "<html><head><title>Current IP Check</title></head>\
               <body>Current IP Address: 128.237.138.116</body></html>"

let () =
  let open Ezxmlm in
  let (_, xml) = from_string example in
  let ip_addr = member "html" xml |>
                member "body" |>
                data_to_string in
  (* Brittle solution *)
  let sub_str_i = (String.rindex content ':') + 2 in
  print_endline (Str.string_after content sub_str_i)

答案 2 :(得分:0)

您可以尝试:

curl ip.sb
curl ipv4.ip.sb
curl ipv6.ip.sb

当前IP地址,IPv4地址和IPv6地址。