C#7.0下没有Range类型,只有在C# 8.0之后语法(.netCore,.netStandard支持8.0)之后才有,但是.netframework目前最高支持到7.0.如果想在.netframework下使用,就需要模拟Range
原文链接:https://www.cnblogs.com/Multi-Heartbeat/p/13227419.html
不过原文有点小bug,完善后代码如下
// define Range object public struct Range { private int startIndex; private int endIndex; private bool isNotNull; public Range(int startIndex, int endIndex) { this.startIndex = startIndex; this.endIndex = endIndex; this.isNotNull = true; } public bool IsNull { get { return !this.isNotNull; } } internal void CheckNull() { if (this.IsNull) { throw new Exception("this object is null"); } } public int StartIndex { get { CheckNull(); return this.startIndex; } } public int EndIndex { get { CheckNull(); return this.endIndex; } } public int Count { get { if (IsNull) { return 0; } return this.endIndex - this.startIndex; } } public static implicit operator Range(string input) { if (string.IsNullOrEmpty(input)) { return default(Range); } Regex re = new Regex(@"^(^?)d+..(^?)d+$"); Regex re3 = new Regex(@"^..(^?)d+$"); Regex re2 = new Regex(@"^(^?)d+..$"); Match match = null; int matchFlag = 0; if (re.IsMatch(input)) { matchFlag = 1; match = re.Match(input); } else if (re2.IsMatch(input)) { matchFlag = 2; match = re2.Match(input); } else if (re3.IsMatch(input)) { matchFlag = 3; match = re3.Match(input); } // match fails if (0 == matchFlag) { return default(Range); } //string[] strs = match.Value.Split(new char[]{ '.','.'}, StringSplitOptions.RemoveEmptyEntries); string[] strs = match.Value.Split(new string[] { ".." }, StringSplitOptions.RemoveEmptyEntries); //两种写法都可以 int startIndex, endIndex; int.TryParse(strs[0].Replace("^", "-"), out startIndex); int.TryParse(strs[1].Replace("^", "-"), out endIndex); if (2 == matchFlag) { endIndex = int.MaxValue; } else if (3 == matchFlag) { startIndex = 0; } return new Range(startIndex, endIndex); } } //添加对string的扩展方法 public static class ObjectExtension { public static string Span(this string val, string input, bool isValidate = true) { if (string.IsNullOrEmpty(val) || string.IsNullOrEmpty(input)) { return val; } Range range = input; return GetString(val, range, isValidate); } public static string Span(this string val, Range range, bool isValidate = true) { if (string.IsNullOrEmpty(val) || range.IsNull) { return val; } return GetString(val, range,isValidate); } private static string GetString(string val, Range range,bool isValidate) { int len = val.Length; int startIndex = range.StartIndex < 0 ? len + range.StartIndex : range.StartIndex; int endIndex = range.EndIndex < 0 ? len + range.EndIndex : range.EndIndex; if (range.EndIndex == int.MaxValue) { endIndex = len; } if (isValidate && startIndex > endIndex) { throw new IndexOutOfRangeException("startIndex must be equal or less than endIndex."); } int count = endIndex - startIndex; return val.Substring(startIndex, count); } }
测试例子
class Program { static void Main(string[] args) { string str = "adfgafd"; Range range = "1..^1"; string str1 = str.Span(range); string str2 = str.Span("1..^1"); } }
结果:dfgaf dfgaf
总体上代码有点复杂,性能也一般,不过不失为一种实现高级语言语法糖的思路