-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStringExtensions.cs
241 lines (213 loc) · 10.8 KB
/
StringExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Annoyances.Net
{
/// <summary>
/// Extensions to <see cref="String"/>
/// </summary>
public static class StringExtensions
{
public static bool Contains(this string s, string substring, CultureInfo culture, CompareOptions options)
{
return culture.CompareInfo.IndexOf(s, substring, options) >= 0;
}
/// <summary>
/// Strips all HTML-like tags from a string
/// </summary>
/// <param name="s">The string to strip tags from</param>
/// <returns>The supplied string without the tags (e.g. "<em>Hello</em>" becomes "Hello")</returns>
public static string StripTags(this string s)
{
const string tagPattern = "<.*?>";
return Regex.Replace(s, tagPattern, string.Empty);
}
/// <summary>
/// Reports the zero-based index of the first occurrence of any of the specified strings in the current string object
/// </summary>
/// <param name="s">The current string object</param>
/// <param name="anyOf">The candidates to seek</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search</param>
/// <param name="match">The string that was matched</param>
/// <returns>The index of the first occurrence or -1 if there are none</returns>
public static int IndexOfAny(this string s, IEnumerable<string> anyOf, StringComparison comparisonType, out string match)
{
return IndexOfAny(s, anyOf, 0, comparisonType, out match);
}
/// <summary>
/// Reports the zero-based index of the first occurrence of any of the specified strings in the current string object
/// </summary>
/// <param name="s">The current string object</param>
/// <param name="anyOf">The candidates to seek</param>
/// <param name="startIndex">The search starting position</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search</param>
/// <param name="match">The string that was matched</param>
/// <returns>The index of the first occurrence or -1 if there are none</returns>
public static int IndexOfAny(this string s, IEnumerable<string> anyOf, int startIndex, StringComparison comparisonType, out string match)
{
int count = s.Length - startIndex;
return IndexOfAny(s, anyOf, startIndex, count, comparisonType, out match);
}
/// <summary>
/// Reports the zero-based index of the first occurrence of any of the specified strings in the current string object
/// </summary>
/// <param name="s">The current string object</param>
/// <param name="anyOf">The candidates to seek</param>
/// <param name="startIndex">The search starting position</param>
/// <param name="count">The number of character positions to examine</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search</param>
/// <param name="match">The string that was matched</param>
/// <returns>The index of the first occurrence or -1 if there are none</returns>
public static int IndexOfAny(this string s, IEnumerable<string> anyOf, int startIndex, int count, StringComparison comparisonType, out string match)
{
return IndexOfAnyCommonBody(anyOf, startIndex, count, comparisonType, s.IndexOf, false, out match);
}
/// <summary>
/// Reports the zero-based index of the last occurrence of any of the specified strings in the current string object
/// </summary>
/// <param name="s">The current string object</param>
/// <param name="anyOf">The candidates to seek</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search</param>
/// <param name="match">The string that was matched</param>
/// <returns>The index of the last occurrence or -1 if there are none</returns>
public static int LastIndexOfAny(this string s, IEnumerable<string> anyOf, StringComparison comparisonType, out string match)
{
int startIndex = s.Length - 1;
return LastIndexOfAny(s, anyOf, startIndex, comparisonType, out match);
}
/// <summary>
/// Reports the zero-based index of the last occurrence of any of the specified strings in the current string object
/// </summary>
/// <param name="s">The current string object</param>
/// <param name="anyOf">The candidates to seek</param>
/// <param name="startIndex">The search starting position. The search proceeds from this position to the start of the string.</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search</param>
/// <param name="match">The string that was matched</param>
/// <returns>The index of the last occurrence or -1 if there are none</returns>
public static int LastIndexOfAny(this string s, IEnumerable<string> anyOf, int startIndex, StringComparison comparisonType, out string match)
{
int count = startIndex + 1;
return LastIndexOfAny(s, anyOf, startIndex, count, comparisonType, out match);
}
/// <summary>
/// Reports the zero-based index of the last occurrence of any of the specified strings in the current string object
/// </summary>
/// <param name="s">The current string object</param>
/// <param name="anyOf">The candidates to seek</param>
/// <param name="startIndex">The search starting position. The search proceeds from this position to the start of the string.</param>
/// <param name="count">The number of character positions to examine</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search</param>
/// <param name="match">The string that was matched</param>
/// <returns>The index of the last occurrence or -1 if there are none</returns>
public static int LastIndexOfAny(this string s, IEnumerable<string> anyOf, int startIndex, int count, StringComparison comparisonType, out string match)
{
return IndexOfAnyCommonBody(anyOf, startIndex, count, comparisonType, s.LastIndexOf, true, out match);
}
private static int IndexOfAnyCommonBody(
IEnumerable<string> anyOf,
int startIndex,
int count,
StringComparison comparisonType,
Func<string, int, int, StringComparison, int> searchFunction,
bool preferHighIndexValues,
out string match)
{
int result = -1;
match = null;
foreach (string candidate in anyOf)
{
int thisIndex = searchFunction(candidate, startIndex, count, comparisonType);
bool candidateIsBetterIgnoringMinusOne = preferHighIndexValues ? thisIndex > result : thisIndex < result;
if (thisIndex != -1 && (result == -1 || candidateIsBetterIgnoringMinusOne))
{
result = thisIndex;
match = candidate;
}
}
return result;
}
/// <summary>
/// Converts a string to a byte array using the specified encoding
/// </summary>
/// <param name="s">The string</param>
/// <param name="encoding">The text encoding to use</param>
/// <returns>The bytes constituting the string</returns>
public static byte[] ToByteArray(this string s, Encoding encoding)
{
if (encoding == null)
{
throw new ArgumentNullException("encoding");
}
return encoding.GetBytes(s);
}
/// <summary>
/// What case does a camel case string start with?
/// </summary>
public enum CamelCaseStartsWith
{
/// <summary>
/// UpperCamelCase
/// </summary>
UpperCase,
/// <summary>
/// lowerCamelCase
/// </summary>
LowerCase
}
/// <summary>
/// Converts a space-delimited string to camel case
/// </summary>
/// <param name="s">The string to convert</param>
/// <param name="caseStarts">What case should the result start with (i.e. UpperCase vs. lowerCase)</param>
/// <param name="culture">Culture for changing the case</param>
/// <returns>The camel case string</returns>
public static string ToCamelCase(this string s, CamelCaseStartsWith caseStarts, CultureInfo culture)
{
if (s == null)
{
throw new ArgumentNullException("s");
}
string[] words = s.Split(' ');
string[] capitalisedWords = words.Select(t => Capitalise(t, culture)).ToArray();
string joined = string.Join("", capitalisedWords);
if (caseStarts == CamelCaseStartsWith.LowerCase && capitalisedWords.Length > 0)
{
// e.g. ThisCamelCase -> thisCamelCase
joined = Capitalise(joined, culture, CamelCaseStartsWith.LowerCase);
}
return joined;
}
private static string Capitalise(string s, CultureInfo culture, CamelCaseStartsWith caseStarts = CamelCaseStartsWith.UpperCase)
{
if (string.IsNullOrWhiteSpace(s))
{
return string.Empty;
}
var firstLetter = new string(new[] { s[0] });
firstLetter = caseStarts == CamelCaseStartsWith.UpperCase ? firstLetter.ToUpper(culture) : firstLetter.ToLower(culture);
var rest = new string(s.ToCharArray(1, s.Length - 1));
return firstLetter + rest;
}
/// <summary>
/// Converts a string from CamelCase by adding spaces (e.g. SomeTerm becomes "Some Term")
/// </summary>
/// <param name="s">The string to convert</param>
/// <returns>The converted string</returns>
public static string FromCamelCase(this string s)
{
if (s == null)
{
throw new ArgumentNullException("s");
}
IEnumerable<string> charOrSpacePlusChar = s.Select((c, i) => OptionalCamelCaseSpace(c, i) + c);
return string.Join("", charOrSpacePlusChar);
}
private static string OptionalCamelCaseSpace(char c, int i)
{
return (i > 0 && char.IsUpper(c)) ? " " : string.Empty;
}
}
}