0

通配符模式是将任何字符匹配到 (?) 并将任何序列字符匹配到 (*) 的文件系统标准。

我正在尝试使用 erlang re:replace/3函数来替换:

a) *进入.*

b) ?进入.

c) .进入\.

d) 如果通配符模式不是以通配符^开头,则在模式的末尾添加一个(正则表达式中的开始匹配)

e) 如果通配符模式不以通配符结尾,则$在模式的末尾添加一个(正则表达式中的结束匹配)

不知何故,我无法获得 re:replace 来实现这一目标。

例子:

尝试根据上面的 a) 项进行替换

re:replace("something*.log","\*","\.\*").
exception error: bad argument
4

2 回答 2

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
于 2013-06-13T12:16:39.527 回答
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"
于 2013-06-13T13:14:50.920 回答