从字符串中以空格分隔和引号括起来的元素获取数据字段

Posted

技术标签:

【中文标题】从字符串中以空格分隔和引号括起来的元素获取数据字段【英文标题】:Get data fields from space-separated and quote-enclosed elements in string 【发布时间】:2019-02-27 12:19:15 【问题描述】:

要处理 api 响应,我需要首先将字符串拆分为单独的字符串字段。字段的数量是固定的(每个始终存在),但“空”字段可以表示为?""。由\n 终止。单个字段可能包含也可能不包含在两个转义引号中,但只有八个字段可能包含空格和其他字符,例如 / % ? :

"A single field / % ?"

并且还可以包含数字或正斜杠,如下所示。

两个字符串的示例,每个有 20 个字段:

14 S 20 ? OSE ? NHY "Norsk Hydro" NO0005052605 1 "20180921" 48.6 2068998276 NOK S I ? ? 1 Y\n

40 S 20 ? OSE ? "" "Boa SBL AS 13/18 FRN C" NO0010675051 1 "20180706" 45 0 NOK B ? ? ? 0.01 Y\n

什么是安全有效的方法?

我知道我可以让它工作,但它不是很优雅..

【问题讨论】:

@Richardissimo 正确,均已更正。 现在明白了。已编辑以显示实际值。 双引号本身可以在带引号的字符串中吗?喜欢“Norsk”“Hydro”,还是“Norsk”“Hydro”“”? @Dialectus 不,双引号仅用于封装完整的字符串。 【参考方案1】:

您可以使用Regex 来查找这些内容(您需要为引用的值做更多的工作)...

var value = @"14 S 20 ? OSE ? NHY ""Norsk Hydro"" NO0005052605 1 ""20180921"" 48.6 2068998276 NOK S I ? ? 1 Y"+"\n";
var pattern = new Regex(@"^(""(.*?)""|[^ ""]+)( (""(.*?)""|[^ ""]+))19,19\n$");
var match = pattern.Match(value);
if (match.Success)

    for (int ctr = 1; ctr < match.Groups.Count; ctr++)
    
        Console.WriteLine("   Group 0:  1", ctr, match.Groups[ctr].Value);
        int captureCtr = 0;
        foreach (Capture capture in match.Groups[ctr].Captures)
        
            Console.WriteLine("      Capture 0: 1",
                captureCtr, capture.Value);
            captureCtr++;
        
    

或者如果您想要一个非正则表达式解决方案:使用string.Split 使用空格,进入Queue&lt;string&gt;s 构造函数,然后在循环中处理队列,Dequeue一次处理每个项目。

如果项目以\" 开头,则有另一个循环Dequeue 进入List&lt;string&gt;,直到相应的项目以右引号结尾,此时,使用string.Join(" ", list) 重构引用的值。

【讨论】:

谢谢!我现在了解“内部”模式(@"^(A|B)( (C|D))19,19\n$" 中 A、B、C、D 的含义)。但是请您解释一下每个内部模式的匹配程度,这些组是否参考了这些内部模式的顺序?例如,我不明白为什么简单地 @"^(A|B)19,19\n$" 不起作用。 您的列表中有 20 个项目,因此我将正则表达式定义为“一个项目”(引用或未引用),后跟 19 个“ 后跟一个项目”实例。 “组”指的是正则表达式中的普通括号(除了第 0 组,它代表整个比赛,所以我跳过了它)。捕获表示该组中找到的各个实例。

以上是关于从字符串中以空格分隔和引号括起来的元素获取数据字段的主要内容,如果未能解决你的问题,请参考以下文章

csv文件

CSV文件格式介绍

CSV文件格式要求

Pig — 如何加载包含用双引号括起来并用逗号分隔的字段的 CSV 文件

Java Scanner - 除非存在引号,否则用空格分隔?

我的 CSV 文件带有双引号括起来的字段 - 无法识别数值“12131”