1 module easyd..string;
2 
3 // (C) 2014-2018 by Matthias Rossmy
4 // This file is distributed under the "Fair Use License v2"
5 
6 import std.conv;
7 import std.stdio;
8 import std..string;
9 
10 unittest
11 {
12 	string s = "Hello World!";
13 	assert(s.countChar('l')==3);
14 	assert(s.contains('!'));
15 	assert(s.contains("or"));
16 	assert(s.subStr(1,4)=="ello");
17 	assert(s.getEnd(1)=="!");
18 	assert(s.cutEnd(7)=="Hello");
19 	assert(s.grow(20,'-',true)=="--------Hello World!");
20 	int[] a = [1,2,3];
21 	assert(a.concat(",")=="1,2,3");
22 }
23 
24 string decPoint(T)(T x)
25 {
26 	return x.to!string.replace(",",".");
27 }
28 
29 size_t countChar(string s, char c)
30 {
31     size_t result = 0;
32     foreach(x;s) if(x==c) result++;
33     return result;
34 }
35 
36 bool contains(T)(string s, T f, size_t start=0, ptrdiff_t* foundAtPos=null)
37 {
38     auto p = s.indexOf(f,start);
39     if(foundAtPos)
40     {
41         *foundAtPos = p;
42     }
43     return p>=0;
44 }
45 
46 long posOf(string s, string f, long start=0, bool returnLengthIfNotFound=false) //not needed in new D versions, use indexOf unless you need returnLengthIfNotFound=true
47 {
48 	//writeln("Searching for "~f~" in "~s~" from position "~start.to!string);
49     long maxpos = s.length.to!long-f.length.to!long;
50     for(long pos=start; pos<=maxpos; pos++)
51     {
52         for(long offset=0; offset<f.length; offset++)
53         {
54             if(s[pos+offset]!=f[offset]) goto next;
55         }
56         return pos;
57         next:;
58     }
59 	return returnLengthIfNotFound? s.length : -1;
60 }
61 
62 struct StringPair
63 {
64 	string first;
65 	string second;
66 	
67 	this(string f, string s="")
68 	{
69 		first=f;
70 		second=s;
71 	}
72 }
73 
74 string replacePH(string s, StringPair placeHolders, string f, string r)
75 {
76 	return replace(s, placeHolders.first~f~placeHolders.second, r);
77 }
78 
79 string subStr(string s, long start, long length=-1)
80 {
81 	if (start > s.length)
82 	{
83 		return "";
84 	}
85 	if (start<0)
86 	{
87 		start = 0;
88 	}
89 	long end;
90 	if (length<0)
91 	{
92 		end = s.length;
93 	}
94 	else
95 	{
96 		end = start+length;
97 	}
98 	if(end>s.length)
99 	{
100 		end=s.length;
101 	}
102 	return s[start..end];
103 }
104 
105 string cutEnd(string s, long count)
106 {
107 	if (s.length > count)
108 	{
109 		return s.subStr(0, s.length - count);
110 	} 
111 	else
112 	{
113 		return "";
114 	}
115 }
116 
117 string getEnd(string s, long count)
118 {
119 	return s.subStr(s.length - count, -1);
120 }
121 
122 string grow(string s, int length, char fillChar=' ', bool atBeginning=false)
123 {
124 	if(s.length>=length) return s;
125 	string fillString;
126 	for(int x=0; x<(length-s.length); x++) fillString ~= fillChar;
127 	if(atBeginning)
128 	{
129 		return fillString ~ s;
130 	}
131 	else
132 	{
133 		return s ~ fillString;
134 	}
135 }
136 
137 string concat(T)(T[] a,string separator="",string delegate(T) tostr = item=>item.to!string)
138 {
139 	string result;
140 	for(int x=0; x<a.length; x++)
141 	{
142 		result ~= tostr(a[x]);
143 		if(x<a.length-1) result ~= separator;
144 	}
145 	return result;
146 }
147 
148 string inputLine()
149 {
150 	return std.stdio.readln.replace("\n","");
151 }
152