Ziffern in Text mit textlicher Entsprechung ersetzen

Ziffern in Text mit textlicher Entsprechung ersetzen

So etwas mag man zwar selten brauchen, aber wenn man es doch einmal benötigt, kann man schon ein paar Stunden daran sitzen.

Da möchte ich dem geneigten Leser die Arbeit zukünftig etwas erleichtern – wenn er genau dasselbe Problem haben sollte.

Das alles basiert auf einer englischen Version von Codeproject, erweitert um die Möglichkeit, in einem String nach Zahlen zu suchen und diese zu ersetzen. (Es werden ganze Zahlen ersetzt, nicht einzelne Ziffern.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
        /// <summary>
        /// replaces all occurrances of numbers with textual representation
        /// text can contain any combination of numbers and text
        /// examples:
        /// var test1 = Tools.StringFuncs.ReplaceNumbersWithText("abc123def");
        /// var test2 = Tools.StringFuncs.ReplaceNumbersWithText("abc 1 def");
        /// var test3 = Tools.StringFuncs.ReplaceNumbersWithText("abc 1,23 def 55 99 3 asfeljaifas 1 aseflrjkwaes");
        /// var test4 = Tools.StringFuncs.ReplaceNumbersWithText("abc12 3def");
        /// var test5 = Tools.StringFuncs.ReplaceNumbersWithText("abc1 23def");
        /// var test6 = Tools.StringFuncs.ReplaceNumbersWithText("abc16543123def");
        /// var test7 = Tools.StringFuncs.ReplaceNumbersWithText("abc1 2008434513 def");
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string ReplaceNumbersWithText(string text)
        {
            string res = "";
            var reminder = text;
            while (true)
            {
                // find all number-occurrences and replace them one by one, keeping
                // remaining string in reminder
                var matches = Regex.Matches(reminder, @"\d+");
                if (matches.Count < 1)
                {
                    res += reminder;
                    break;
                }
                var match = matches[0];
                res += reminder.Substring(0, match.Index);
                int n = 0;
                int.TryParse(match.Value, out n);
                res += ConvertNumberToString(n);
                reminder = reminder.Substring(match.Index + match.Length);
            }
            return res;
        }
 
        /// <summary>
        /// converts any number between 0 & INT_MAX (2,147,483,647)
        /// https://www.codeproject.com/Articles/1164635/Converting-Numbers-to-Text-in-Csharp
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static string ConvertNumberToString(int n)
        {
            if (n < 0)
                throw new NotSupportedException("negative Zahlen sind nicht unterstützt");
            if (n == 0)
                return "null";
            if (n < 10)
                return ConvertDigitToString(n);
            if (n < 20)
                return ConvertTeensToString(n);
            if (n < 100)
                return ConvertHighTensToString(n);
            if (n < 1000)
                return ConvertBigNumberToString(n, (int)1e2, "hundert");
            if (n < 1e6)
                return ConvertBigNumberToString(n, (int)1e3, "tausend");
            if (n < 1e9)
                return ConvertBigNumberToString(n, (int)1e6, "millionen");
            //if (n < 1e12)
            return ConvertBigNumberToString(n, (int)1e9, "milliarden");
        }
 
        private static string ConvertDigitToString(int i)
        {
            switch (i)
            {
                case 0: return "";
                case 1: return "ein";
                case 2: return "zwei";
                case 3: return "drei";
                case 4: return "vier";
                case 5: return "fünf";
                case 6: return "sechs";
                case 7: return "sieben";
                case 8: return "acht";
                case 9: return "neun";
                default:
                    throw new IndexOutOfRangeException(String.Format("{0} ist keine Ziffer", i));
            }
        }
 
        //assumes a number between 10 & 19
        private static string ConvertTeensToString(int n)
        {
            switch (n)
            {
                case 10: return "zehn";
                case 11: return "elf";
                case 12: return "zwölf";
                case 13: return "dreizehn";
                case 14: return "vierzehn";
                case 15: return "fünfzehn";
                case 16: return "sechzehn";
                case 17: return "siebzehn";
                case 18: return "achtzehn";
                case 19: return "neunzehn";
                default:
                    throw new IndexOutOfRangeException(String.Format("{0} keine Zehner", n));
            }
        }
 
        //assumes a number between 20 and 99
        private static string ConvertHighTensToString(int n)
        {
            int tensDigit = (int)(Math.Floor((double)n / 10.0));
 
            string tensStr;
            switch (tensDigit)
            {
                case 2: tensStr = "zwanzig"; break;
                case 3: tensStr = "dreißig"; break;
                case 4: tensStr = "vierzig"; break;
                case 5: tensStr = "fünfzig"; break;
                case 6: tensStr = "sechzig"; break;
                case 7: tensStr = "siebzig"; break;
                case 8: tensStr = "achtzig"; break;
                case 9: tensStr = "neunzig"; break;
                default:
                    throw new IndexOutOfRangeException(String.Format("{0} nicht im Bereich 20-99", n));
            }
            if (n % 10 == 0) return tensStr;
            string onesStr = ConvertDigitToString(n - tensDigit * 10);
            return onesStr + "und" + tensStr;
        }
 
        /// <summary>
        /// This is the primary conversion method which can convert any integer bigger than 99
        /// </summary>
        /// <param name="n">The numeric value of the integer to be translated ("textified")</param>
        /// <param name="baseNum">Represents the order of magnitude of the number (e.g., 100 or 1000 or 1e6, etc)</param>
        /// <param name="baseNumStr">The string representation of the base number (e.g. "hundred", "thousand", or "million", etc)</param>
        /// <returns>Textual representation of any integer</returns>
        private static string ConvertBigNumberToString(int n, int baseNum, string baseNumStr)
        {
            // special case: use commas to separate portions of the number, unless we are in the hundreds
            string separator = ""; // (baseNumStr != "hundert") ? ", " : " ";
 
            // Strategy: translate the first portion of the number, then recursively translate the remaining sections.
            // Step 1: strip off first portion, and convert it to string:
            int bigPart = (int)(Math.Floor((double)n / baseNum));
            string bigPartStr = ConvertNumberToString(bigPart) + baseNumStr;
            // Step 2: check to see whether we're done:
            if (n % baseNum == 0) return bigPartStr;
            // Step 3: concatenate 1st part of string with recursively generated remainder:
            int restOfNumber = n - bigPart * baseNum;
            return bigPartStr + separator + ConvertNumberToString(restOfNumber);
        }

Das sieht dann so aus, Programmcode und Ausgabe gemischt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
            var res = new List<string>{ Tools.StringFuncs.ReplaceNumbersWithText("abc123def"),
            Tools.StringFuncs.ReplaceNumbersWithText("abc 1 def"),
            Tools.StringFuncs.ReplaceNumbersWithText("abc 1,23 def 55 99 3 asfeljaifas 1 aseflrjkwaes"),
            Tools.StringFuncs.ReplaceNumbersWithText("abc12 3def"),
            Tools.StringFuncs.ReplaceNumbersWithText("abc1 23def"),
            Tools.StringFuncs.ReplaceNumbersWithText("abc16543123def"),
            Tools.StringFuncs.ReplaceNumbersWithText("abc1 2008434513 def"),};
            System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, res));
 
Ausgabe:
abceinhundertdreiundzwanzigdef
abc ein def
abc ein,dreiundzwanzig def fünfundfünfzig neunundneunzig drei asfeljaifas ein aseflrjkwaes
abczwölf dreidef
abcein dreiundzwanzigdef
abcsechzehnmillionenfünfhundertdreiundvierzigtausendeinhundertdreiundzwanzigdef
abcein zweimilliardenachtmillionenvierhundertvierunddreißigtausendfünfhundertdreizehn def

One thought on “Ziffern in Text mit textlicher Entsprechung ersetzen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.