我出现了以下代码,以替换Find
中所有Replace
w / Request
的出现。把答案放在Result
。这是使用DCG,因此它们都是字符代码列表。客户端代码将使用的谓词是substitute
。
findReplace(_, _, [], []) -->
[]. % The end.
findReplace(Find, Replace, Result, ResultRest) -->
Find, % Found Find.
{ append(Replace, Intermediate, Result) }, % Put in Replace in Find's place.
!, % Make sure we don't backtrack & interpret Find as the next case.
findReplace(Find, Replace, Intermediate, ResultRest).
findReplace(Find, Replace, [ C | Intermediate ], ResultRest) -->
[ C ], % Any other character.
findReplace(Find, Replace, Intermediate, ResultRest).
substitute(Find, Replace, Request, Result):-
phrase(findReplace(Find, Replace, Result, []), Request).
这适用于SWI-Prolog。有没有人对我如何改进它有任何意见?我正在学习如何使用DCG&差异清单。例如,我放入剪辑,以便在找到Find
后,prolog不会回溯&将其解释为[ C ]
案例中的普通字符。这是否需要,或者是否有一种更具说明性的方式呢?
另一个问题 - 是否有一个谓词已经可以用替代品做同样的事情,可能是在原子上?
提前致谢。
答案 0 :(得分:10)
考虑使用semicontext表示法替换DCG中的子序列:
eos([], []).
replace(_, _) --> call(eos), !.
replace(Find, Replace), Replace -->
Find,
!,
replace(Find, Replace).
replace(Find, Replace), [C] -->
[C],
replace(Find, Replace).
substitute(Find, Replace, Request, Result):-
phrase(replace(Find, Replace), Request, Result).
示例:
?- substitute("a", "b", "atesta", R), atom_codes(A, R).
R = [98, 116, 101, 115, 116, 98],
A = btestb.
另外,underscores_are_much_more_readable thanMixedCaseNamesAsYouSee。
答案 1 :(得分:2)
关于第二个问题,即使用原子,我写了这个实用程序,只读atomic_list_concat
%% replace_word(+Old, +New, +Orig, -Replaced)
%% is det.
%
% string replacement
% doesn't fail if not found
%
replace_word(Old, New, Orig, Replaced) :-
atomic_list_concat(Split, Old, Orig),
atomic_list_concat(Split, New, Replaced).
示例:
?- replace_word(a, b, atesta, X).
X = btestb.