public static string AsBracketNotation(string[] indicies) { if (indicies == null) { throw new ArgumentNullException(nameof(indicies)); } var sb = new StringBuilder(); foreach (var index in indicies) { if (sb.Length == 0) { sb.Append('$'); } else { sb.Append('['); if (RegExp.IsMatch(index, @"^[0-9*]+$")) { sb.Append(index); } else { sb.Append('\'').Append(index).Append('\''); } sb.Append(']'); } } return(sb.ToString()); }
IEnumerable <T> Trace <T>(TraceArgs args, Func <object, string[], T> resultor) { var stack = new Stack <TraceArgs>(); stack.Push(args); while (stack.Count > 0) { var popped = stack.Pop(); var expr = popped.Expr; var value = popped.Value; var path = popped.Path; if (string.IsNullOrEmpty(expr)) { if (path != null) { yield return(resultor(value, path.Split(Semicolon))); } continue; } var i = expr.IndexOf(';'); var atom = i >= 0 ? expr.Substring(0, i) : expr; var tail = i >= 0 ? expr.Substring(i + 1) : string.Empty; if (value != null && _system.HasMember(value, atom)) { stack.Push(Args(tail, Index(value, atom), path + ";" + atom)); } else if (atom == "*") { Walk(atom, tail, value, path, (m, l, x, v, p) => stack.Push(Args(m + ";" + x, v, p))); } else if (atom == "..") { Walk(atom, tail, value, path, (m, l, x, v, p) => { var result = Index(v, m.ToString()); if (result != null && !_system.IsPrimitive(result)) { stack.Push(Args("..;" + x, result, p + ";" + m)); } }); stack.Push(Args(tail, value, path)); } else if (atom.Length > 2 && atom[0] == '(' && atom[atom.Length - 1] == ')') // [(exp)] { stack.Push(Args(_eval(atom, value, path.Substring(path.LastIndexOf(';') + 1)) + ";" + tail, value, path)); } else if (atom.Length > 3 && atom[0] == '?' && atom[1] == '(' && atom[atom.Length - 1] == ')') // [?(exp)] { Walk(atom, tail, value, path, (m, l, x, v, p) => { var result = _eval(RegExp.Replace(l, @"^\?\((.*?)\)$", "$1"), Index(v, m.ToString()), m.ToString()); if (Convert.ToBoolean(result, CultureInfo.InvariantCulture)) { stack.Push(Args(m + ";" + x, v, p)); } }); } else if (RegExp.IsMatch(atom, @"^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$")) // [start:end:step] Python slice syntax { foreach (var a in Slice(atom, tail, value, path).Reverse()) { stack.Push(a); } } else if (atom.IndexOf(',') >= 0) // [name1,name2,...] { foreach (var part in RegExp.Split(atom, @"'?,'?").Reverse()) { stack.Push(Args(part + ";" + tail, value, path)); } } } }
public void TestString_Match() { Assert.IsTrue(_exp.IsMatch("ababc")); }
public void TestPositive_Match0() { bool result = _exp.IsMatch("1112222"); Assert.IsTrue(result); }
IEnumerable <T> Trace <T>(TraceArgs args, Func <object, string[], T> resultor) { var stack = new Stack <TraceArgs>(); stack.Push(args); while (stack.Count > 0) { var popped = stack.Pop(); var expr = popped.Expr; var value = popped.Value; var path = popped.Path; if (string.IsNullOrEmpty(expr)) { if (path != null) { yield return(resultor(value, path.Split(_Semicolon))); } continue; } var i = expr.IndexOf(';'); var atom = i >= 0 ? expr.Substring(0, i) : expr; var tail = i >= 0 ? expr.Substring(i + 1) : string.Empty; var hasMember = false; var d = value as IDictionary <string, object>; if (null != d) { if (d.ContainsKey(atom)) { hasMember = true; } } else { var l = value as IList <object>; if (null != l) { int ii; if (int.TryParse(atom, out ii)) { if (-1 < ii && l.Count > ii) { hasMember = true; } } } } if (hasMember) { stack.Push(Args(tail, _Index(value, atom), path + ";" + atom)); } else if (atom == "*") { Walk(atom, tail, value, path, (m, l, x, v, p) => stack.Push(Args(m + ";" + x, v, p))); } else if (atom == "..") { Walk(atom, tail, value, path, (m, l, x, v, p) => { var result = _Index(v, m.ToString()); var isPrim = true; d = result as IDictionary <string, object>; if (null == d) { if (null != result as IList <object> ) { isPrim = false; } } else { isPrim = false; } if (!isPrim) { stack.Push(Args("..;" + x, result, p + ";" + m)); } }); stack.Push(Args(tail, value, path)); } else if (atom.Length > 2 && atom[0] == '(' && atom[atom.Length - 1] == ')') // [(exp)] { stack.Push(Args(_eval(atom, value, path.Substring(path.LastIndexOf(';') + 1)) + ";" + tail, value, path)); } else if (atom.Length > 3 && atom[0] == '?' && atom[1] == '(' && atom[atom.Length - 1] == ')') // [?(exp)] { Walk(atom, tail, value, path, (m, l, x, v, p) => { var result = _eval(RegExp.Replace(l, @"^\?\((.*?)\)$", "$1"), _Index(v, m.ToString()), m.ToString()); if (Convert.ToBoolean(result, CultureInfo.InvariantCulture)) { stack.Push(Args(m + ";" + x, v, p)); } }); } else if (RegExp.IsMatch(atom, @"^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$")) // [start:end:step] Phyton slice syntax { foreach (var a in Slice(atom, tail, value, path).Reverse()) { stack.Push(a); } } else if (atom.IndexOf(',') >= 0) // [name1,name2,...] { foreach (var part in RegExp.Split(atom, @"'?,'?").Reverse()) { stack.Push(Args(part + ";" + tail, value, path)); } } } }