Jef*_*ood -2 .net regex formatting text
鉴于以下文字
/feeds/tag/remote-desktop 1320 17007 22449240 /feeds/tag/terminal-server 1328 15805 20989040 /foo/23211/test 1490 11341 16898090
假设我们想将这些数字转换为他们的逗号形式,就像这样
/feeds/tag/remote-desktop 1,320 17,007 22,449,240 /feeds/tag/terminal-server 1,328 15,805 20,989,040 /foo/23211/test 1,490 11,341 16,898,090
(不要担心修复固定宽度的ASCII间距,这是另一天的问题)
这是我能想到的最好的正则表达式; 它基于Regex Ninja Steven Levithan的JavaScript正则表达式解决方案:
return Regex.Replace(s, @"\b(?<!\/)\d{4,}\b(?<!\/)",
delegate(Match match) {
string output = "";
string m = match.Value;
int len = match.Length;
for (int i = len - 1; i >= 0 ; i--)
{
output = m[i] + output;
if ((len - i) % 3 == 0) output = "," + output;
}
if (output.StartsWith(","))
output = output.Substring(1, output.Length-1);
return output;
});
Run Code Online (Sandbox Code Playgroud)
在一个相关的问题中,有一个非常聪明的数字逗号插入正则表达式建议:
text = Regex.Replace(text, @"(?<=\d)(?=(\d{3})+$)", ",")
Run Code Online (Sandbox Code Playgroud)
然而,这需要一个结束锚$
,正如您所看到的,我在上面的文本中没有 - 数字在文本的其余部分中"浮动".
我怀疑有一种比我的解决方案更清洁的方法吗?写完这篇文章之后,我才意识到我可以将它们组合在一起,并将一个Regex放在另一个中,就像这样:
return Regex.Replace(s, @"\b(?<!\/)\d{4,}\b(?<!\/)",
delegate(Match match) {
return Regex.Replace(match.Value, @"(?<=\d)(?=(\d{3})+$)", ",");
});
Run Code Online (Sandbox Code Playgroud)
mac*_*kow 17
为什么你不能将它们解析为long然后使用格式化的ToString?
CultureInfo ci = new CultureInfo("en-US");
long number = 1234;
Console.WriteLine(number.ToString("N0", ci));
Run Code Online (Sandbox Code Playgroud)
我原则上同意那些建议你尽可能使用内置.NET格式化设施的建议.
但是,如果您的数字可以任意大,那么这样的事情应该有效:
int len = match.Length;
int numCommas = (len-1) / 3;
StringBuilder sb = new StringBuilder(match.Value, len + numCommas)
for (int i = 1; i <= numCommas; i++) {
sb.Insert(len - i * 3, ',');
}
return sb.ToString()
Run Code Online (Sandbox Code Playgroud)
此外,如果您Regex.Replace
因任何原因坚持使用,您可以调整问题中列出的正则表达式以避免结束锚点问题.例如,我认为
Regex.Replace(text, @"(?<=\d)(?=(\d{3})+(\s|$))", ",")
Run Code Online (Sandbox Code Playgroud)
可以在你的例子中工作,因为你想要"逗号"的数字都跟着空格或行尾.
为什么不(在你的代表内):
CultureInfo ci = new CultureInfo("en-US");
string output = int.Parse(match.Value).ToString("N0",ci);
Run Code Online (Sandbox Code Playgroud)
翻译: