使用数字和千位分隔符修复格式错误的字符串
Posted
技术标签:
【中文标题】使用数字和千位分隔符修复格式错误的字符串【英文标题】:Fixing badly formatted string with number and thousands seperator 【发布时间】:2019-05-20 10:39:36 【问题描述】:我收到一个字符串,其中包含与数字中的字符相同的数字、空值和分隔符。也有包含逗号的数字引号。使用 C#,我想解析字符串,这样我就有了一个很好的、管道分隔的数字系列,没有逗号,2 个小数位。
我尝试了标准替换,删除了某些字符串模式来清理它,但我不能满足所有情况。我首先删除了引号,但是当千位分隔符变成分隔符时,我得到了额外的数字。我尝试将Regex.Replace
与通配符一起使用,但由于引号内有多个带有引号和逗号的数字,因此无法从中得到任何东西。
为 Silvermind 编辑:temp = Regex.Replace(temp, "(?:\",.*\")","($1 = .\n )");
我无法控制我收到的文件。我可以清理大部分数据。当字符串如下所示时,就有问题了:
703.36,751.36,"1,788.36",887.37,891.37,"1,850.37",843.37,"1,549,797.36",818.36,749.36,705.36,0.00,"18,979.70",934.37
我是否应该查找引号字符,找到下一个引号字符,从这两个字符之间的所有内容中删除逗号,然后继续?这是我要去的地方,但那里必须有更优雅的东西(是的 - 我不经常用 C# 编程 - 我是 DBA)。
我希望看到千位分隔符被删除,并且没有引号。
【问题讨论】:
始终显示您尝试过的内容。 (请将其编辑到您的问题中) 这在我看来像 CSV。尝试一些 CSV 阅读器/解析器(例如 CSVHelper),它可以帮助您轻松解决解析问题。 这将删除逗号和引号(修复字符串):@"""|(? 【参考方案1】:此正则表达式模式将匹配字符串中的所有单个数字:
(".*?")|(\d+(.\d+)?)
(".*?")
匹配 "123.45"
之类的东西
(\d+(.\d+)?)
匹配 123.45
或 123
从那里,您可以对每个匹配项进行简单的搜索和替换,以获得一个“干净”的数字。
完整代码:
var s = "703.36,751.36,\"1,788.36\",887.37,891.37,\"1,850.37\",843.37,\"1,549,797.36\",818.36,749.36,705.36,0.00,\"18,979.70\",934.37";
Regex r = new Regex("(\".*?\")|(\\d+(.\\d+)?)");
List<double> results = new List<double>();
foreach (Match m in r.Matches(s))
string cleanNumber = m.Value.Replace("\"", "");
results.Add(double.Parse(cleanNumber));
Console.WriteLine(string.Join(", ", results));
输出:
703.36, 751.36, 1788.36, 887.37, 891.37, 1850.37, 843.37, 1549797.36, 818.36, 749.36, 705.36, 0, 18979.7, 934.37
【讨论】:
谢谢 - 这是我一直在寻找的“优雅”。非常感谢!【参考方案2】:使用跟踪状态的解析器类型解决方案更容易解决。正则表达式适用于常规文本,只要您有上下文,就很难用正则表达式解决。像这样的东西会起作用。
internal class Program
private static string testString = "703.36,751.36,\"1,788.36\",887.37,891.37,\"1,850.37\",843.37,\"1,549,797.36\",818.36,749.36,705.36,0.00,\"18,979.70\",934.37";
private static void Main(string[] args)
bool inQuote = false;
List<string> numbersStr = new List<string>();
int StartPos = 0;
StringBuilder SB = new StringBuilder();
for(int x = 0; x < testString.Length; x++)
if(testString[x] == '"')
inQuote = !inQuote;
continue;
if(testString[x] == ',' && !inQuote )
numbersStr.Add(SB.ToString());
SB.Clear();
continue;
if(char.IsDigit(testString[x]) || testString[x] == '.')
SB.Append(testString[x]);
if(SB.Length != 0)
numbersStr.Add(SB.ToString());
var nums = numbersStr.Select(x => double.Parse(x));
foreach(var num in nums)
Console.WriteLine(num);
Console.ReadLine();
【讨论】:
谢谢 - 我更喜欢这个,而不是我的逐字符方法。下面来自 MikeH 的正则表达式得到了我一直在寻找的优雅。以上是关于使用数字和千位分隔符修复格式错误的字符串的主要内容,如果未能解决你的问题,请参考以下文章