Anonymous user
Commatizing numbers: Difference between revisions
→{{header|D}}: replaced extra features version with more solidly tested version
(→{{header|D}}: inserted missing braces) |
(→{{header|D}}: replaced extra features version with more solidly tested version) |
||
Line 236:
=={{header|D}}==
Better to have more tests than more features.
<lang d>import std.stdio, std.regex, std.range;
auto decIntField = ctRegex!("0(?![0-9])|[1-9][0-9]*");▼
// A decimal fractional field is joined by only a point, and is only digits.▼
auto decFracField = ctRegex!("(?<=^\\.)[0-9]+");▼
auto commatize(in char[] txt, in uint start=0, in uint step=3,
in string ins=",") @safe
in {
assert(step > 0);
Line 251 ⟶ 246:
if (start > txt.length || step > txt.length)
return txt;
auto matchInt = matchFirst(txt[start .. $], decIntField);▼
if (!matchInt)▼
return txt[0 .. start] ~ matchInt.pre ~▼
.replace!(m => m.hit.retro.chunks(step).join(ins).retro)(decIntField) ~▼
matchInt.post▼
.replace!(m => m.hit.chunks(step).join(ins))(decFracField);▼
}▼
// First number may begin with digit or decimal point. Exponents ignored.
enum decFloField = ctRegex!("[0-9]*\\.[0-9]+|[0-9]+");
return txt;
// Within a decimal float field:
void main() {▼
// A decimal integer field to commatize is positive and not after a point.
foreach (const line; "commatizing_numbers_data.txt".File.byLine)▼
line.commatizeSpec!true(0, 3, ",", ["Z$":"."]).writeln;▼
}
unittest {
// An attempted solution may have one or more of the following errors:
// ignoring a number that has only zero before its decimal point
assert("0.0123456".commatize == "0.012,345,6");
// commatizing numbers other than the first
assert("1000 2.3000".commatize == "1,000 2.3000");
// only commatizing in one direction from the decimal point
assert("0001123.456789".commatize == "0001,123.456,789");
// detecting prefixes such as "Z$" requires detecting other prefixes
assert("
// detecting a decimal field that isn't attached to the first number
assert(" 2600 and .0125".commatize
//
assert("
// ignoring a number that begins with a point, or treating it as integer
assert("
▲}
▲void main() {
"pi=3.14159265358979323846264338327950288419716939937510582097494459231"
.commatize(0, 5, " ").writeln;
"The author has two Z$100000000000000 Zimbabwe notes (100 trillion)."
▲ foreach (const line; "
line.commatize.writeln;
}</lang>
{{out}}
Line 335 ⟶ 301:
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
$-140,000±100 millions.
6/9/1946 was a good year for some.</pre>
|