Jump to content

Commatizing numbers: Difference between revisions

Line 236:
 
=={{header|D}}==
<lang d>import std.stdio, std.regex, std.stringrange, std.rangearray, std.algorithm, std.convtypecons;
 
auto commatize(bool smart=false)(in char[] txt, in uint start=0, in uint step=3, in string ins=",")
string ins=",", string[string] specials=null)
/*pure nothrow*/ @safe in {
in {
assert(step > 0);
} body {
Line 245 ⟶ 246:
return txt;
 
returnauto preSpan = txt[0 .. start] ~ txt[start .. $];
auto scanSpan = txt[start .. $];
.replaceAll!(m => m.hit.retro.chunks(step).join(ins).retro)
 
("[1-9][0-9]*".regex);
// The first number field begins with zero then no digit, or non-zero.
auto numField = regex("0(?![0-9])|[1-9][0-9]*");
auto matchNum = matchFirst(scanSpan, numField);
 
if (!matchNum)
return txt;
 
// Pass only a point and capture a decimal fractional field, if any.
auto decField = regex("(?<=^\\.)[0-9]+");
 
static if (smart) {
// A fractional part over 33 digits needs a word for less than a
// decillionth (to read aloud in US number names).
// Group by 5 with spaces to read like scientific notation instead.
auto matchDec = matchFirst(matchNum.post, decField);
if (matchDec && matchDec.hit.length > 33) {
step = 5;
ins = " ";
}
// A whole part over 36 digits needs a word for more than a decillion
// (to read aloud in US number names).
// Group anyway, with spaces as in the task's Wikipedia reference.
else if (matchNum.hit.length > 36) {
ins = " ";
}
}
 
// There may be special prefixed formats that use different separators.
// Any format with a longer prefix should override a shorter one.
Tuple!(string, string)[] pairs;
foreach (pair; specials.byPair) {
pairs ~= pair;
}
std.algorithm.sort!("a[0].length < b[0].length")(pairs);
foreach (symbol; pairs) {
if (matchNum.pre.length >= symbol[0].length &&
symbol[0] == matchNum.pre[$ - symbol[0].length .. $])
ins = symbol[1];
}
 
return preSpan ~ matchNum.pre ~ matchNum.hit
.replaceAllreplace!(m => m.hit.retro.chunks(step).join(ins).retro)(numField)
~ matchNum.post
.replace!(m => m.hit.chunks(step).join(ins))(decField);
}
 
void main() {
// Current New Zealand dollar format overrides old Zimbabwe dollar format.
foreach (const line; "commatizing_numbers_data.txt".File.byLine)
line.commatize!true(0, 3, ",", ["Z$":".write", "NZ$":","]).writeln;
}
 
unittest {
assert("0.0123456".commatize == "0.012,345,6");
assert("1. NZ$300000".commatize(1, 3, " ", ["Z$":".", "NZ$":","]) ==
"1. NZ$300,000");
assert("1000 2.3000".commatize == "1,000 2.3000");
assert("0001123.456789".commatize == "0001,123.456,789");
}</lang>
{{out}}
<pre>pi=3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510 58209 74944 59231
<pre>pi=3.14,159,265,358,979,323,846,264,338,327,950,288,419,716,939,937,510,582,097,494,459,231
The author has two Z$100,.000,.000,.000,.000 Zimbabwe notes (100 trillion).
"-in Aus$+1,411.8millions"
===US$0017,440 millions=== (in 2,0002000 dollars)
123.e8,000e8000 is pretty big.
The land area of the earth is 57,268,900(29% of the surface) square miles.
Ain't no numbers in this here words, nohow, no way, Jose.
James was never known as 0000000007
Arthur Eddington wrote: I believe there are 15, 747, 724, 136, 275, 002, 577, 605, 653, 961, 181, 555, 468, 044, 717, 914, 527, 116, 709, 366, 231, 425, 076, 185, 631, 031, 296 protons in the universe.
$-140,000±100 millions.
6/9/1,9461946 was a good year for some.</pre>
 
=={{header|J}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.