0

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?

Anderson Green
  • 30,230
  • 67
  • 195
  • 328
  • What do you expect for `replace_substring("aa","a","b", R)`? – false Apr 10 '18 at 09:08
  • 2
    `replace_substring("abc", "bc", "23", R).` will succeed, but `replace_substring("abc", "b", "2", R).` will fail since your implementation only succeeds if the substring being replaced is a suffix of the original string. – lurker Apr 10 '18 at 18:27

1 Answers1

1

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
    ).
shuji
  • 7,369
  • 7
  • 34
  • 49
lurker
  • 56,987
  • 9
  • 69
  • 103