算術演算可能な文字列

2021/09/02に公開

C# - C# 文字列内の数値に加算する方法|teratail

上記質問を見て、時に便利なこともあるかと思って作ってみました。

public static class ArithmeticStringExtension
{
	public static ArithmeticString ToArithmeticString(this string source) => new ArithmeticString(source);
}

public class ArithmeticString
{
	public static explicit operator string(ArithmeticString source) => source.ToString();

	public static explicit operator int(ArithmeticString source) => source.Value;

	public static implicit operator ArithmeticString(string source) => new ArithmeticString(source);

	public static ArithmeticString operator +(ArithmeticString a) => new ArithmeticString(a.Template, +a.Value);

	public static ArithmeticString operator -(ArithmeticString a) => new ArithmeticString(a.Template, -a.Value);

	public static ArithmeticString operator ~(ArithmeticString a) => new ArithmeticString(a.Template, ~a.Value);

	public static ArithmeticString operator ++(ArithmeticString a) => new ArithmeticString(a.Template, a.Value + 1);

	public static ArithmeticString operator --(ArithmeticString a) => new ArithmeticString(a.Template, a.Value - 1);

	public static ArithmeticString operator +(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value + i);

	public static ArithmeticString operator +(int i, ArithmeticString a) => new ArithmeticString(a.Template, i + a.Value);

	public static ArithmeticString operator -(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value - i);

	public static ArithmeticString operator -(int i, ArithmeticString a) => new ArithmeticString(a.Template, i - a.Value);

	public static ArithmeticString operator *(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value * i);

	public static ArithmeticString operator *(int i, ArithmeticString a) => new ArithmeticString(a.Template, i * a.Value);

	public static ArithmeticString operator /(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value / i);

	public static ArithmeticString operator /(int i, ArithmeticString a) => new ArithmeticString(a.Template, i / a.Value);

	public static ArithmeticString operator %(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value % i);

	public static ArithmeticString operator %(int i, ArithmeticString a) => new ArithmeticString(a.Template, i % a.Value);

	public static ArithmeticString operator &(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value & i);

	public static ArithmeticString operator &(int i, ArithmeticString a) => new ArithmeticString(a.Template, i & a.Value);

	public static ArithmeticString operator |(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value | i);

	public static ArithmeticString operator |(int i, ArithmeticString a) => new ArithmeticString(a.Template, i | a.Value);

	public static ArithmeticString operator ^(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value ^ i);

	public static ArithmeticString operator ^(int i, ArithmeticString a) => new ArithmeticString(a.Template, i ^ a.Value);

	public static ArithmeticString operator <<(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value << i);

	public static ArithmeticString operator >>(ArithmeticString a, int i) => new ArithmeticString(a.Template, a.Value >> i);

	public ArithmeticString(string source)
	{
		var s = Regex.Replace(source, @"[{}]", a => a.Value + a.Value);
		var match = Regex.Match(s, @"(.*?)(\d+)(.*)");
		if (match.Success)
		{
			Value = int.Parse(match.Groups[2].Value);
			Template = $"{match.Groups[1].Value}{{0:{new string('0', match.Groups[2].Length)}}}{match.Groups[3].Value}";
		}
		else
		{
			Value = 0;
			Template = s + "{0}";
		}
	}

	public ArithmeticString(string template, int value)
	{
		(Template, Value) = (template, value);
	}

	public string Template { get; private set; }
	public int Value { get; private set; }

	private string text;

	public override string ToString() => text ??= string.Format(Template, Value);
}

次のように使います。

for (var a = "No001".ToArithmeticString(); a.Value < 20; a++)
{
	Console.WriteLine(a);
}

実行結果

No001
No002
No003
No004
No005
No006
No007
No008
No009
No010
No011
No012
No013
No014
No015
No016
No017
No018
No019

まったく便利なことはありませんでした。

for (int i = 1; i < 20; i++)
{
	Console.WriteLine($"No{i:000}");
}

執筆日: 2020/10/22

GitHubで編集を提案

Discussion