# Is this the best way to replace characters in a string?

**URL:** <https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640>\
**Category:** General\
**Created:** [May 14, 2019, 5:29pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640 "2019-05-14T17:29:27Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [May 14, 2019, 5:29pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/1 "2019-05-14T17:29:27Z")

</div>

A snag I hit in my blog tutorial was text needed to be checked for single quotes before inserting them into an SQL database, and if so the single quotes needed to be escaped SQL-style.

My solution is:

```prolog
sql_escape_single_quotes(StringIn, StringOut) :-
  split_string(StringIn, "'", "", List),
  atomics_to_string(List, "''", StringOut).

```

It seems to work well, and I’m very proud of it… which probably means there’s some horrible bug lurking in there somewhere.

BTW: I’ve nearly finished Unit 3 which explains how to join a PostgreSQL database to a SWI Prolog web application at [GitHub - roblaing/swipl-webapp-howto: Some simple examples of how to use SWI Prolog as a webserver](https://github.com/roblaing/swipl-webapp-howto)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [May 14, 2019, 5:51pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/2 "2019-05-14T17:51:22Z")

</div>

My 2 cents worth.

Did you write test cases for it and check the boundary conditions? If so and it works then move on. To [quote](https://en.wikiquote.org/wiki/Donald_Knuth) Donald Knuth.

" **premature optimization is the root of all evil (or at least most of it) in programming**.

Remember you can always update it later. Most people who read your blog are probably more interested in seeing the dots connected than seeing perfect shinny dots. 🙂

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [May 14, 2019, 6:20pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/3 "2019-05-14T18:20:28Z")

</div>

Is this needed? The ODBC interface allows using "?"s in the query, which are substituted at query execution time.  
[http://www.swi-prolog.org/pldoc/man?section=odbc-param-query](http://www.swi-prolog.org/pldoc/man?section=odbc-param-query)

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [May 14, 2019, 7:26pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/4 "2019-05-14T19:26:47Z")

</div>

I’m a big fan of literate programming and test driven development, and hope to write a follow up howto on those for SWI Prolog at some stage. (I’m not aware of good ways of doing these for web development, other than eyeballing the error messages in the browser if something is broken).

A reason I’m working through the old Udacity course again and re-implementing it in SWI Prolog is it avoids the common tutorial problem of sticking to examples a given language is good at and there are often repeated solutions for, and there was no way of avoiding making ASCII art not make odbc\_query choke without solving the escaping single quote problem in a way which I assume is a common problem in Prolog.

I only realised Steve Huffman’s genius in picking that project while I was working through it.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [December 19, 2019, 2:21pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/5 "2019-12-19T14:21:28Z")

</div>

Just made use of your code.

One slight modification I made was to add some type checking, e.g. [must\_be/2](https://www.swi-prolog.org/pldoc/man?predicate=must_be/2) See: [Hoare logic](https://en.wikipedia.org/wiki/Hoare_logic)

```prolog
normalize_string(In,Out) :-
    must_be(string,In),
    split_string(In,"\n","\s\t\n",List),
    atomics_to_string(List, " ", Out),
    must_be(string,Out).

```

The final check is probably not needed, but in all my initial code I find that having extreme type checking finds bugs I would have never seen otherwise. Latter when the code is passing all of the test and humming along, most to all of the type checks can be commented out or removed all together.

---

<div class="post-metadata">

**Author:** ![mgondan1](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/mgondan1/32/803_2.png) [@mgondan1](https://swi-prolog.discourse.group/u/mgondan1)\
**Post date:** [December 19, 2019, 3:16pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/6 "2019-12-19T15:16:21Z")

</div>

One unrelated, but related thing: 😀

At some point you use ‘action(/)’ in one of your forms. I found it in unit2. That’s not needed. In fact it invokes the root folder, which is not always desired behavior.

Best wishes

Matthias

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [December 19, 2019, 3:23pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/7 "2019-12-19T15:23:45Z")

</div>

Thanks @mgondan1, I need to refactor the tutorial soon. At the moment, I’m redoing it in Erlang which I hope to put on github soon. I find Erlang and Prolog nicely complimentary.

---

<div class="post-metadata">

**Author:** ![esad](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/esad/32/884_2.png) [@esad](https://swi-prolog.discourse.group/u/esad)\
**Post date:** [April 26, 2020, 8:59pm UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/8 "2020-04-26T20:59:06Z")

</div>

Btw. using PCRE library, the escaping of quotes would be a simple `re_replace('"'/g, '""',Input,Output)`.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 27, 2020, 7:34am UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/9 "2020-04-27T07:34:24Z")

</div>

> [@EricGT](#):
>
> The final check is probably not needed

Neither is IMO the first. split\_string/4 does the type checking for you. Less code is easier to read and uses less resources (time and space). Runtime type checking is typically best left to automatic instrumentation such that it doesn’t clutter code and can be disabled in a final version. Using (type) property declarations you also open the path to static analysis (with all its problems).

There are a number of packages to achieve that. At some point there should be proper default infrastructure. For now, my heuristics are

- If predicates that do type checking are called that do most of the job for free, do not add type checks.
- Add the to public predicates that may easily fail when used with the wrong type given some likelihood that the predicate is easily misused.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [April 27, 2020, 10:42am UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/10 "2020-04-27T10:42:28Z")

</div>

> [@jan](#):
>
> Using (type) property declarations you also open the path to static analysis (with all its problems).

What problems are you eluding too?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 28, 2020, 7:03am UTC](https://swi-prolog.discourse.group/t/is-this-the-best-way-to-replace-characters-in-a-string/640/11 "2020-04-28T07:03:47Z")

</div>

> [@EricGT](#):
>
> What problems are you eluding too?

We have seen many type systems passing by in the Prolog community. Prolog is a bit of a nasty beast though. Net to classical types we have instantiation, multiple modes and the search pattern for a solution that may make certain subtrees of the search tree only accessible with some restricted type or the negation thereof. You can solve that by restricting the language, but then you cannot call it Prolog anymore. You can also look for an annotation format that can describe this complexity. Ciao did probably the most relevant and complete work here. The result is rather complex to use and proving type correctness quickly becomes unrealistic.

I’m not saying there is no solution. Recent developments for type systems in dynamically typed languages (another issue) may help. Its not easy though.
