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



我正在编写一个询问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的人可以用正确的方式指出我吗?

您不说自己想做什么。由于答案来自中等可靠的来源,因此假设您只想提取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>,更复杂的标签文本等之类的东西)您可以通过使此代码更加聪明来做出响应(例如,以 last 4的数字,您在页面上看到的数字)。或者,您可以屈服并实际开始解析HTML。我的建议:不要尝试为此使用正则表达式,请使用真正的HTML解析器。

不需要正则表达式。

这是一个自我包含的示例,它应该与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)

您可以尝试:

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

对于当前的IP地址,IPv4地址和IPv6地址。

最新更新