3

序言中是否可以用某个给定字符替换字符串的所有空格?示例-如果我有一个变量How are you today? 并且我想要How_are_you_today?

4

3 回答 3

3

这完全取决于字符串的含义。SWI 有几个,其中一些通常在任何常见的 Prolog 中都可用,并且符合 ISO 标准;有些是特定于 SWI 的,不符合要求。因此,让我们从通常可用的那些开始:

作为字符代码列表的字符串 — 表示代码点的整数

这种表示通常是默认值,在 SWI 7 之前,它也是 SWI 中的默认值。最大的缺点是现在可以将任意整数列表与文本混淆。

:- set_prolog_flag(double_quotes, codes).

codes_replaced(Xs, Ys) :-
   maplist(space_repl, Xs, Ys).

space_repl(0' ,0'_).
space_repl(C, C) :- dif(C,0' ).

?- codes_replaced("Spaces  !", R).
R = [83, 112, 97, 99, 101, 115, 95, 95, 33] ;
false.

字符串作为字符列表——长度为 1 的原子

这种表示更简洁一些,因为它不会将整数与字符混淆,请参阅此回复如何获得更紧凑的答案。

:- set_prolog_flag(double_quotes, chars).

chars_replaced(Xs, Ys) :-
   maplist(space_replc, Xs, Ys).

space_replc(' ','_').
space_replc(C, C) :- dif(C,' ').

?- chars_replaced("Spaces  !", R).
R = ['S', p, a, c, e, s, '_', '_', !] ;
false.

字符串作为原子

@WouterBeek 已经向您展示了如何使用特定于 SWI 的内置插件来完成此操作。我将在上面重用:

atom_replaced(A, R) :-
   atom_chars(A, Chs),
   chars_replaced(Chs, Rs),
   atom_chars(R, Rs).

?- atom_replaced('Spaces  !',R).
R = 'Spaces__!' ;
false.

到目前为止,一切都适用于

字符串作为特定于 SWI 的不合格数据类型

此版本不适用于任何其他系统。我提到它是为了完整性。

于 2014-11-17T14:02:35.360 回答
3

对于原子

可能有一些方法可以做到这一点。我发现以下特别简单,使用atomic_list_concat/3

?- atomic_list_concat(Words, ' ', 'How are you today?'), atomic_list_concat(Words, '_', Result).
Words = ['How', are, you, 'today?'],
Result = 'How_are_you_today?'.

对于 SWI 字符串

以上也可以用 SWI 字符串完成。不幸的是,没有string_list_concat/3什么可以使转换变得微不足道。split_string/4用途非常广泛,但它只完成了一半的工作:

?- split_string("How are you today?", " ", "", Words).
Words = ["How", "are", "you", "today?"].

我们可以定义string_list_concat/3自己(定义它的第一次尝试如下所示)或者我们需要稍微不同的方法,例如重复string_concat/3

string_list_concat(Strings, Separator, String):-
  var(String), !,
  maplist(atom_string, [Separator0|Atoms], [Separator|Strings]),
  atomic_list_concat(Atoms, Separator0, Atom),
  atom_string(Atom, String).
string_list_concat(Strings, Separator, String):-
  maplist(atom_string, [Separator0,Atom], [Separator,String]),
  atomic_list_concat(Atoms, Separator0, Atom),
  maplist(atom_string, Atoms, Strings).

接着:

?- string_list_concat(Words, " ", "How are you today?"), string_list_concat(Words, "_", Result).
Words = ["How", "are", "you", "today?"],
Result = "How_are_you_today?".
于 2014-11-17T13:41:47.297 回答
2

SWI-Prolog DCGs 允许使用“后推”或前瞻参数进行简单定义:

?- phrase(rep_string(` `, `_`), `How are you`, R),atom_codes(A,R).
R = [72, 111, 119, 95, 97, 114, 101, 95, 121|...],
A = 'How_are_you'

定义是

rep_string(Sought, Replace), Replace --> Sought, rep_string(Sought, Replace).
rep_string(Sought, Replace), [C] --> [C], rep_string(Sought, Replace).
rep_string(_, _) --> [].

编辑为了避免多个“解决方案”,一种可能性是

rep_string(Sought, Replace), Replace --> Sought, !, rep_string(Sought, Replace).
rep_string(Sought, Replace), [C] --> [C], !, rep_string(Sought, Replace).
rep_string(_, _) --> [].
于 2014-11-17T15:11:23.480 回答