通配符模式是文件系统标准,它将任何字符与(?)匹配,任何序列字符与(*)匹配。
我正在尝试使用erlang re:replace/3函数替换:
a)*
加入.*
b)?
进入.
c).
进入\.
d)如果通配符模式没有在通配符中启动,则在模式的末尾添加^
(正则表达式中的起始匹配)
e)如果通配符模式不以通配符结尾,则在模式的末尾添加$
(正则表达式中的结束匹配)
不知怎的,我无法得到re:replace来实现这个目标。
示例:
尝试根据上面的项目a)替换
re:replace("something*.log","\*","\.\*").
exception error: bad argument
答案 0 :(得分:1)
如果您对规范的完整性有信心,可以直接编写转换(我猜没有性能问题,因为正则表达式通常是短列表)
-module(rep).
-compile([export_all]).
replace(L) when is_list(L) -> lists:reverse(replace(L,wildcard(hd(L)))).
% take care of the first character
replace(L,W={true,_}) -> replace(L,W,[]);
replace(L,W={false,_}) -> replace(L,W,[$^]).
% take care of the last character
replace([_],{true,R},Res) -> R ++ Res;
replace([_],{false,R},Res) -> [$$|R] ++ Res;
% middle characters
replace([_|Q],{_,R},Res) -> replace(Q,wildcard(hd(Q)),R++Res).
wildcard($*) -> {true,[$*,$.]};
wildcard($?) -> {true,[$.]};
wildcard($.) -> {true,[$.,$\\]};
wildcard(C) -> {false,[C]}.
以你的例子:
11> rep:replace("something*.log").
"^something.*\\.log$"
请注意,\\是一个单个字符,您可以通过以下方式进行验证:
12> length(rep:replace("something*.log")).
18
答案 1 :(得分:0)
在re:replace
来电:
re:replace("something*.log","\*","\.\*").
反斜杠实际上并没有在字符串中结束,因为它们只是逃避了以下字符。一些反斜杠转义具有特殊含义,例如"\n"
表示换行符,但不会让角色保持不变:
4> "\*".
"*"
所以你需要一个反斜杠的双反斜杠来实际上成为字符串的一部分:
5> re:replace("something*.log","\\*","\.\*").
[<<"something">>,<<".*">>|<<".log">>]
请注意,不需要"\.\*"
中的反斜杠。
上面的返回值是一个iolist,它通常非常有用(特别是如果你想将结果写入文件或套接字),但有时你可能需要一个额外内存和CPU成本的普通字符串。您可以将第四个参数传递给re:replace
:
7> re:replace("something*.log","\\*","\.\*", [{return, list}]).
"something.*.log"