Replacing substrings in Prolog [duplicate]

2019-09-20 07:23发布

This question already has an answer here:

In order to replace a substring in a string, I wrote a predicate called replace_substring. It uses SWI-Prolog's append/3 predicate:

:- initialization(main).
:- set_prolog_flag(double_quotes, chars). 

main :-
    replace_substring("this is a string","string","replaced string",Result),
    writeln(Result).

replace_substring(String,To_Replace,Replace_With,Result) :-
    append(First,To_Replace,String),
    append(First,Replace_With,Result).

Still, I'm not sure if this is the most efficient way to replace substrings in Prolog. Does Prolog have a built-in predicate that could be used for the same purpose?

1条回答
Lonely孤独者°
2楼-- · 2019-09-20 07:59

The short answer is, no, Prolog does not have a built-in string replace predicate. What you show will only replace the substring if that substring is at the end of the original string. That is, it will replace "abc" in the string "xyzabc" but not in the string "xyabcz".

You can use append/2:

replace_substring(String, To_Replace, Replace_With, Result) :-
    append([Front, To_Replace, Back], String),
    append([Front, Replace_With, Back], Result).

If you want it to succeed without replacing on a non-match, then:

replace_substring(String, To_Replace, Replace_With, Result) :-
    (    append([Front, To_Replace, Back], String)
    ->   append([Front, Replace_With, Back], Result)
    ;    Result = String
    ).

As @false hints in his question, do you want to handle replacing multiple occurrences? If so, the extension to your method would be:

replace_substring(String, To_Replace, Replace_With, Result) :-
    (    append([Front, To_Replace, Back], String)
    ->   append([Front, Replace_With, Back], R),
         replace_substring(Back, To_Replace, Replace_with, Result)
    ;    Result = String
    ).
查看更多
登录 后发表回答