OCaml:如何从字符串中删除所有非字母字符?

时间:2014-11-07 22:17:18

标签: regex unicode ocaml

如何从字符串中删除所有非字母字符?

E.g。

"Wë_1ird?!"  ->  "Wëird"

在Perl中,我使用=~ s/[\W\d_]+//g执行此操作。在Python中,我使用

re.sub(ur'[\W\d_]+', u'', u"Wë_1ird?!", flags=re.UNICODE)

AFAICT,Str.regex不支持\W\d等。(我无法支持) 告诉它是否支持Unicode,但不知怎的,我怀疑它。)

2 个答案:

答案 0 :(得分:6)

Str不支持Unicode。假设您正在处理UTF-8编码数据。您可以按如下方式使用UutfUucp

let keep_alpha s =
  let b = Buffer.create 255 in
  let add_alpha () _ = function
  | `Malformed _ -> Uutf.Buffer.add_utf_8 b Uutf.u_rep
  | `Uchar u -> if Uucp.Alpha.is_alphabetic u then Uutf.Buffer.add_utf_8 b u
  in
  Uutf.String.fold_utf_8 add_alpha () s;
  Buffer.contents b

# keep_alpha "Wë_1ird?!";;
- : string = "Wëird"

答案 1 :(得分:1)

我不是regex和utf的专家,但如果我在你的鞋子里,那么我会使用re2库,这是我的第一个近似值:

open Core.Std
open Re2.Std
open Re2.Infix

let drop _match = ""

let keep_alpha s = Re2.replace ~/"\\PL" ~f:drop s

前三行打开库并将其定义纳入范围。您不需要打开库来使用它,但是否则您需要为每个定义添加前缀。 OCaml核心库是以这种方式专门设计的,用户应该打开Std子模块以将所有必要的定义带到范围。 Re2库来自同一个人并且具有一致性约定。 open Re2.Infix会将中缀(和前缀运算符)带到作用域,即~/,它将从字符串创建正则表达式。 drop函数只是忽略它的参数并返回一个空字符串。我使用下划线加前缀参数,因为它是未使用参数的约定(由编译器遵守)。您也可以使用简单的uderscore作为外卡,例如let drop _ = ""。接下来是keep_alpha函数,它将替换任何不与utf字母类匹配的utf符号和空字符串,即将其从输出中删除。

更新

我检查了我的代码并修复了错误。另外,我想展示一下如何在顶层播放这段代码。您有几个选项,但最简单的方法是使用coretop库附带的core脚本。它使用utop顶层,因此请确保已安装它:

 $ opam install -y utop

一旦完成,你就可以开始兴奋了:

 $ coretop -require re2

-require re2标志会自动查找并加载re2库到您的顶层。您可以使用以下命令加载其他库而无需重新启动utop

 # #require "libname";;

第一个#是一个顶级提示,你不应该输入它,但第二个是指令的开头,所以确保实际输入它。任何指令都应从#符号开始。在utop中还有其他有用的指令,即:

 # #use "filename.ml";;   (* will load and evaluate filename.ml      *)
 # #list;;                (* will list all available packages        *)
 # #typeof "keep_alpha";; (* will infer and print type of expression *)

在您使用;;序列终止代码之前,Toplevel不会评估您的代码。您有时可能会在实际代码中看到这个丑陋的;;,但它不是必需的,只是说顶层,您希望它在此处评估您的代码,并向您显示结果。< / p>