将指数数字字符串表示形式拆分为幂和指数

本文关键字:指数 拆分 表示 数字 数字字符 字符串 | 更新日期: 2023-09-27 17:55:42

我有来自指数形式的资源的字符串,如下所示:2⁴ .我想知道是否有办法将其拆分为:

var base = 2; //or even "2", this is also helpful since it can be parsed

var exponent = 4;

我也搜索了互联网和msdn标准数字格式字符串,但我无法找到这种情况的解决方案。

将指数数字字符串表示形式拆分为幂和指数

您可以将数字之间的映射添加到上标数字,然后从源中选择所有数字(这将是base)和所有其他数字 - exponent

const string superscriptDigits = "⁰¹²³⁴⁵⁶⁷⁸⁹";
var digitToSuperscriptMapping = superscriptDigits.Select((c, i) => new { c, i })
                                .ToDictionary(item => item.c, item => item.i.ToString());
const string source = "23⁴⁴";
var baseString = new string(source.TakeWhile(char.IsDigit).ToArray());
var exponentString = string.Concat(source.SkipWhile(char.IsDigit).Select(c => digitToSuperscriptMapping[c]));

现在,您可以将baseexponent转换为int。此外,在执行转化代码之前,您还需要验证输入。


甚至没有映射:

var baseString = new string(source.TakeWhile(char.IsDigit).ToArray());
var exponentString = string.Concat(source.SkipWhile(char.IsDigit).Select(c => char.GetNumericValue(c).ToString()));

您可以将正则表达式与 String.Normalize 一起使用:

var value = "42⁴³";
var match = Regex.Match(value, @"(?<base>'d+)(?<exponent>[⁰¹²³⁴-⁹]+)");
var @base = int.Parse(match.Groups["base"].Value);
var exponent = int.Parse(match.Groups["exponent"].Value.Normalize(NormalizationForm.FormKD));
Console.WriteLine($"base: {@base}, exponent: {exponent}");

指数的格式在英语中称为上标。如果您使用该关键字进行搜索,您可以找到许多与此相关的问题。

上标中的数字在 Unicode 中映射为:

0 -> 'u2070
1 -> 'u00b9
2 -> 'u00b2
3 -> 'u00b3
4 -> 'u2074
5 -> 'u2075
6 -> 'u2076
7 -> 'u2077
8 -> 'u2078
9 -> 'u2079

您可以在字符串中搜索该值:

Lis<char> superscriptDigits = new List<char>(){ 
    ''u2070', 'u00b9', 'u00b2', 'u00b3', 'u2074', 
'u2075', 'u2076', 'u2077', 'u2078', 'u2079"};
//the rest of the string is the expontent. Join remaining chars.
str.SkipWhile( ch => !superscriptDigits.Contains(ch) ); 

你明白了

您可以使用一个简单的正则表达式(如果您的源代码非常干净):

string value = "2⁴⁴";
string regex = @"(?<base>'d+)(?<exp>.*)";
var matches = Regex.Matches(value, regex);
int b;
int exp = 0;
int.TryParse(matches[0].Groups["base"].Value, out b);
foreach (char c in matches[0].Groups["exp"].Value)
{
    exp = exp * 10 + expToInt(c.ToString());
}
Console.Out.WriteLine("base is : {0}, exponent is {1}", b, exp);

expToInt(基于 Unicode 下标和上标):

public static int expToInt(string c)
{
    switch (c)
    {
        case "'u2070":
            return 0;
        case "'u00b9":
            return 1;
        case "'u00b2":
            return 2;
        case "'u00b3":
            return 3;
        case "'u2074":
            return 4;
        case "'u2075":
            return 5;
        case "'u2076":
            return 6;
        case "'u2077":
            return 7;
        case "'u2078":
            return 8;
        case "'u2079":
            return 9;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

这将输出:

基数为 2,exp 为 44