hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

replace.ha (1769B)


      1 // License: MPL-2.0
      2 // (c) 2021 Eyal Sawady <ecs@d2evs.net>
      3 // (c) 2021 Vlad-Stefan Harbuz <vlad@vladh.net>
      4 
      5 use bytes;
      6 
      7 // Returns a new string duplicated from 's', but with all instances of 'needle'
      8 // replaced with 'target'. The caller must free the return value.
      9 export fn replace(s: str, needle: str, target: str) str = {
     10 	return multireplace(s, (needle, target));
     11 };
     12 
     13 // For each tuple given by 'repls', a replacement of 's' is done like in
     14 // [[replace]], in the order that they are passed as arguments. This function is
     15 // nearly equivalent to calling [[replace]] multiple times, except only one new
     16 // string is allocated. The caller must free the return value.
     17 export fn multireplace(s: str, repls: (str, str)...) str = {
     18 	let res = toutf8(dup(s));
     19 	for (let i = 0z; i < len(repls); i += 1) {
     20 		let needle = toutf8(repls[i].0);
     21 		let target = toutf8(repls[i].1);
     22 		let idx = 0z;
     23 		for (true) {
     24 			idx = match(bytes::index(res[idx..], needle)) {
     25 			case let s: size =>
     26 				yield s + idx;
     27 			case void =>
     28 				break;
     29 			};
     30 			delete(res[idx..idx + len(needle)]);
     31 			insert(res[idx], target...);
     32 			idx += len(target);
     33 		};
     34 	};
     35 	return fromutf8(res);
     36 };
     37 
     38 @test fn replace() void = {
     39 	assert(replace("Hello world!", "world", "there") == "Hello there!");
     40 	assert(replace("I like dogs, dogs, birds, dogs", "dogs", "cats") ==
     41 		"I like cats, cats, birds, cats");
     42 	assert(replace("aaaaaa", "aa", "a") == "aaa");
     43 	assert(replace("aaa", "a", "aa") == "aaaaaa");
     44 	assert(replace("こんにちは", "にち", "ばん") == "こんばんは");
     45 };
     46 
     47 @test fn multireplace() void = {
     48 	assert(multireplace("Hello world", ("Hello", "Greetings"),
     49 		("world", "globe")) == "Greetings globe");
     50 	assert(multireplace("ababa", ("a", "ba"), ("b", "a"), ("a", "c")) ==
     51 		"cccccccc");
     52 };