Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
HarmonizedTextMap.cs
1using System.Collections.Generic;
2using System.Text.RegularExpressions;
3
4namespace Waher.Runtime.Text
5{
10 public class HarmonizedTextMap
11 {
12 private readonly Dictionary<string, MappingExpression> mappings = new Dictionary<string, MappingExpression>();
13 private MappingStep mappingsStep0 = null;
14 private bool hasMaps = false;
15
21 {
22 }
23
30 public void RegisterMapping(string RegexPattern, string MapTo)
31 {
32 this.RegisterMapping(RegexPattern, MapTo, null);
33 }
34
43 public void RegisterMapping(string RegexPattern, string MapTo, object Tag)
44 {
45 lock (this.mappings)
46 {
47 if (!this.mappings.TryGetValue(RegexPattern, out MappingExpression Exp))
48 {
49 Exp = new MappingExpression()
50 {
51 Pattern = RegexPattern,
52 Expression = new Regex(RegexPattern, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant),
53 Tag = Tag
54 };
55 this.mappings[RegexPattern] = Exp;
56 }
57
58 Dictionary<string, bool> Names = new Dictionary<string, bool>();
59
60 foreach (string Name in Exp.Expression.GetGroupNames())
61 Names[Name] = true;
62
63 List<KeyValuePair<int, string>> Parameters = new List<KeyValuePair<int, string>>();
64 int i = MapTo.IndexOf('{');
65 int j;
66
67 while (i >= 0)
68 {
69 j = MapTo.IndexOf('}', i + 1);
70 if (j < 0)
71 break;
72
73 string Name = MapTo.Substring(i + 1, j - i - 1);
74
75 if (Names.ContainsKey(Name))
76 {
77 Parameters.Add(new KeyValuePair<int, string>(i, Name));
78 MapTo = MapTo.Remove(i, j - i + 1);
79 i = MapTo.IndexOf('{', i);
80 }
81 else
82 i = MapTo.IndexOf('{', i + 1);
83 }
84
85 Parameters.Reverse();
86
87 Exp.MapSeed = MapTo;
88 Exp.Parameters = Parameters.ToArray();
89
90 this.hasMaps = true;
91 this.mappingsStep0 = null;
92 }
93 }
94
100 public bool UnregisterMapping(string RegexPattern)
101 {
102 lock (this.mappings)
103 {
104 if (this.mappings.Remove(RegexPattern))
105 {
106 this.hasMaps = this.mappings.Count > 0;
107 this.mappingsStep0 = null;
108 return true;
109 }
110 else
111 return false;
112 }
113 }
114
120 public int UnregisterMappings(object Tag)
121 {
122 if (Tag is null)
123 return 0;
124
125 LinkedList<string> ToRemove = null;
126 int NrRemoved = 0;
127
128 lock (this.mappings)
129 {
130 foreach (KeyValuePair<string, MappingExpression> P in this.mappings)
131 {
132 if (!(P.Value.Tag is null) && P.Value.Tag.Equals(Tag))
133 {
134 if (ToRemove is null)
135 ToRemove = new LinkedList<string>();
136
137 ToRemove.AddLast(P.Key);
138 }
139 }
140
141 if (!(ToRemove is null))
142 {
143 foreach (string Key in ToRemove)
144 {
145 if (this.mappings.Remove(Key))
146 NrRemoved++;
147 }
148 }
149 }
150
151 return NrRemoved;
152 }
153
160 public bool TryMap(string InputString, out string Harmonized)
161 {
162 Harmonized = null;
163
164 if (this.hasMaps)
165 {
166 MappingStep Step = this.mappingsStep0;
167 MappingStep Next;
168 char ch2;
169
170 if (Step is null)
171 {
172 MappingExpression[] Expressions;
173
174 lock (this.mappings)
175 {
176 Expressions = new MappingExpression[this.mappings.Count];
177 this.mappings.Values.CopyTo(Expressions, 0);
178 }
179
180 Step = this.mappingsStep0 = MappingStep.CalcStep((char)0, Expressions);
181 }
182
183 foreach (char ch in InputString)
184 {
185 if (!(Step.Expressions is null))
186 {
187 foreach (Mapping Map in Step.Expressions)
188 {
189 Match M = Map.Expression.Match(InputString);
190 if (M.Success && M.Index == 0 && M.Length == InputString.Length)
191 {
192 Harmonized = Map.MapSeed;
193 foreach (KeyValuePair<int, string> P in Map.Parameters)
194 Harmonized = Harmonized.Insert(P.Key, M.Groups[P.Value]?.Value ?? string.Empty);
195
196 return true;
197 }
198 }
199 }
200
201 if (Step.Next is null)
202 return false;
203
204 Next = null;
205
206 foreach (MappingStep Step2 in Step.Next)
207 {
208 ch2 = Step2.Character;
209 if (ch2 == ch)
210 {
211 Next = Step2;
212 break;
213 }
214 else if (ch2 > ch)
215 return false;
216 }
217
218 if (Next is null)
219 return false;
220
221 Step = Next;
222 }
223
224 if (!(Step.Next is null))
225 return false;
226
227 if (!(Step.Expressions is null))
228 {
229 foreach (Mapping Map in Step.Expressions)
230 {
231 Match M = Map.Expression.Match(InputString);
232 if (M.Success && M.Index == 0 && M.Length == InputString.Length)
233 {
234 Harmonized = Map.MapSeed;
235 foreach (KeyValuePair<int, string> P in Map.Parameters)
236 Harmonized = Harmonized.Insert(P.Key, M.Groups[P.Value]?.Value ?? string.Empty);
237
238 return true;
239 }
240 }
241 }
242 }
243
244 return false;
245 }
246
247 private class Mapping
248 {
249 public Regex Expression;
250 public string MapSeed;
251 public KeyValuePair<int, string>[] Parameters;
252 }
253
254 private class MappingExpression
255 {
256 public string Pattern;
257 public Regex Expression;
258 public string MapSeed;
259 public KeyValuePair<int, string>[] Parameters;
260 public object Tag;
261 }
262
263 private class MappingStep
264 {
265 public char Character;
266 public MappingStep[] Next;
267 public Mapping[] Expressions;
268
269 internal static MappingStep CalcStep(char Character, MappingExpression[] Expressions)
270 {
271 SortedDictionary<char, List<MappingExpression>> Next = new SortedDictionary<char, List<MappingExpression>>();
272 List<Mapping> Maps = null;
273 List<MappingStep> Steps = null;
274
275 foreach (MappingExpression Exp in Expressions)
276 {
277 if (string.IsNullOrEmpty(Exp.Pattern))
278 AddMap(ref Maps, Exp);
279 else
280 {
281 char ch = Exp.Pattern[0];
282
283 if ("\\^$.|?*+()[{".IndexOf(ch) >= 0)
284 AddMap(ref Maps, Exp);
285 else
286 {
287 if (!Next.TryGetValue(ch, out List<MappingExpression> List))
288 {
289 List = new List<MappingExpression>();
290 Next[ch] = List;
291 }
292
293 List.Add(new MappingExpression()
294 {
295 Pattern = Exp.Pattern.Substring(1),
296 Expression = Exp.Expression,
297 MapSeed = Exp.MapSeed,
298 Parameters = Exp.Parameters,
299 Tag = Exp.Tag
300 });
301 }
302 }
303 }
304
305 foreach (KeyValuePair<char, List<MappingExpression>> P in Next)
306 {
307 if (Steps is null)
308 Steps = new List<MappingStep>();
309
310 Steps.Add(CalcStep(P.Key, P.Value.ToArray()));
311 }
312
313 return new MappingStep()
314 {
315 Character = Character,
316 Next = Steps?.ToArray(),
317 Expressions = Maps?.ToArray()
318 };
319 }
320
321 private static void AddMap(ref List<Mapping> Maps, MappingExpression Exp)
322 {
323 if (Maps is null)
324 Maps = new List<Mapping>();
325
326 Maps.Add(new Mapping()
327 {
328 Expression = Exp.Expression,
329 MapSeed = Exp.MapSeed,
330 Parameters = Exp.Parameters
331 });
332 }
333
334 public override string ToString()
335 {
336 return new string(this.Character, 1);
337 }
338 }
339 }
340}
Maps strings of text to a harmonized set of strings using collections of regular expressions and para...
int UnregisterMappings(object Tag)
Unregisters mappings tagged with a specific object.
void RegisterMapping(string RegexPattern, string MapTo)
Registers a mapping.
bool TryMap(string InputString, out string Harmonized)
Tries to map a string using registered mappings.
void RegisterMapping(string RegexPattern, string MapTo, object Tag)
Registers a mapping.
HarmonizedTextMap()
Maps strings of text to a harmonized set of strings using collections of regular expressions and para...
bool UnregisterMapping(string RegexPattern)
Unregisters a mapping.
Represents a sub-sequence of symbols.
Definition: Step.cs:12
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.