目标:为了能够拆分以下字符串:"command/test \/ escaped/"
进入以下列表:["command", "test / escaped"]
当前正则表达式如下所示:
Str.split (Str.regexp "/") string_to_split;;
这太简单了,我需要通过在反斜杠前面加上字符串来逃避。
我尝试了这个:Str.regexp "((?!\\).)/"
但它不适用于产生的Ocaml解析器:uncaught exception Failure("spurious \) in regular expression")
有什么想法吗?
我应该提一下,我注意到Ocaml-parser会自动转义字符串中的反斜杠,所以字符串就像:
"foobar\/barfoo"
已转换为"foobar\\/barfoo"
。所以也许实际上想要删除字符串中所有偶数反斜杠。
答案 0 :(得分:3)
你需要两次逃避反斜杠:
所以正确的正则表达式是Str.regexp "((?!\\\\).)/"
。
但是,该正则表达式不起作用。
我建议改为其他3个解决方案:
match_beginning
等手动进行搜索和分割,'/'
字符的简单拆分,并根据需要重新组合字符串\\/
个字符替换为另一个组合,比如\\§
(或者您希望处理的文本中不太可能出现的其他字符串),进行拆分,然后在每个字符中进行反向替换substring(这次只用'/'代替'§'。如果'/'
中的"\\/"
有一个很好的替换字符,那么最后一个可能是最快的。
答案 1 :(得分:1)
这是一个不太明显的解决方案:
let rec split s = Scanf.sscanf s "%s@/%s@\n" (fun left right ->
let llen = String.length left in
let (left, escaped) =
if llen > 0 && left.[llen - 1] = '\\' then
(String.sub left 0 (llen - 1), true)
else
(left, false) in
if right = "" then
[left]
else match split right with
h :: t when escaped ->
(left ^ "/" ^ h) :: t|
ht ->
left :: ht
);;
输出:
# split "command/test \\/ escaped/";;
- : string list = ["command"; "test / escaped"]
虽然有点过于神秘,但仍然可以完成这项任务。
希望这有帮助!
答案 2 :(得分:0)
AFAIR, Str.regexp 不支持!
构建。
然而,PCRE-OCaml库确实:
# #directory "+pcre";;
# #load "pcre.cma";;
# Pcre.split
~rex:(Pcre.regexp ~flags:[`EXTENDED] "(?<!\\\\)/")
"command/test \\/ escaped/"
;;
- : string list = ["command"; "test \\/ escaped"]
如果您想摆脱\/
字符串转义,您将需要后处理拆分的结果或(更好)使用匹配和建立自己的列表。