寻找正则表达式以大字符串查找带引号的换行符(适用于C#)

寻找正则表达式以大字符串查找带引号的换行符(适用于C#)

Looking for Regex to find quoted newlines in a big string (for C#)

我有一个很大的字符串(我称它为CSV文件,尽管实际上不是一个,但现在会更简单),我必须在C#代码中进行解析。
解析过程的第一步是通过仅使用StreamReader对象并调用ReadLine直到文件通过,将文件分成几行。 但是,任何给定的行都可能包含带引号(单引号)的文字和嵌入的换行符。 我需要找到这些换行符,并将它们临时转换为其他类型的令牌或转义序列,直到将文件拆分成行数组为止。然后可以将其改回。

输入数据示例:

1
2
3
1,2,10,99,'Some text without a newline', true, false, 90
2,1,11,98,'This text has an embedded newline
                and continues here'
, true, true, 90

我可以使用string.IndexOf来找到引用的部分并在其中查找换行符,从而编写完成此操作所需的所有C#代码,但我认为正则表达式可能是一个更好的选择(即,现在我有两个问题)


使用C#2.0迭代器使完成此类工作的状态机变得容易。希望这是我将要编写的最后一个CSV解析器。整个文件被视为一串可枚举的字符串,即行/列。 IEnumerable很棒,因为它可以由LINQ运算符处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class CsvParser
{
    public char FieldDelimiter { get; set; }

    public CsvParser()
        : this(',')
    {
    }

    public CsvParser(char fieldDelimiter)
    {
        FieldDelimiter = fieldDelimiter;
    }

    public IEnumerable<IEnumerable<string>> Parse(string text)
    {
        return Parse(new StringReader(text));
    }
    public IEnumerable<IEnumerable<string>> Parse(TextReader reader)
    {
        while (reader.Peek() != -1)
            yield return parseLine(reader);
    }

    IEnumerable<string> parseLine(TextReader reader)
    {
        bool insideQuotes = false;
        StringBuilder item = new StringBuilder();

        while (reader.Peek() != -1)
        {
            char ch = (char)reader.Read();
            char? nextCh = reader.Peek() > -1 ? (char)reader.Peek() : (char?)null;

            if (!insideQuotes && ch == FieldDelimiter)
            {
                yield return item.ToString();
                item.Length = 0;
            }
            else if (!insideQuotes && ch == '\
'
&& nextCh == '\
'
) //CRLF
            {
                reader.Read(); // skip LF
                break;
            }
            else if (!insideQuotes && ch == '\
'
) //LF for *nix-style line endings
                break;
            else if (ch == '"' && nextCh == '"') // escaped quotes""
            {
                item.Append('"');
                reader.Read(); // skip next"
            }
            else if (ch == '"')
                insideQuotes = !insideQuotes;
            else
                item.Append(ch);
        }
        // last one
        yield return item.ToString();
    }

}

请注意,逐字符读取文件,其代码决定何时将换行符视为行定界符或带引号的字符串的一部分。


由于这不是真正的CSV文件,因此它具有任何形式的架构吗?

从您的示例中,您看起来像:
int,int,int,int,string,bool,bool,int

这样就构成了您的记录/对象。

假设您的数据格式正确(我对您的消息来源了解不足,不足以知道此假设的有效性);你可以:

  • 阅读您的台词。
  • 使用状态机来解析您的数据。
  • 如果您的行结束,并且您正在解析字符串,请阅读下一行并继续进行解析。
  • 如果可能,我会避免使用正则表达式。


    如果将整个文件放入一个变量,然后根据未引用的换行符将其拆分怎么办?


    编辑:对不起,我误解了您的帖子。如果您正在寻找正则表达式,那么这里是一个:

    1
    2
    content = Regex.Replace(content,"'([^']*)\
    ([^']*)'"
    ,"'\\1TOKEN\\2'");

    可能存在一些极端情况,并且存在两个问题,但我认为大多数时候都可以。 Regex的作用是,它首先找到之间有\ n的任何一对单引号,然后用TOKEN替换该\ n并保留中间的任何文本。

    但是仍然,我会像下面的@bryansh一样去状态机。


    推荐阅读

      linux分隔文件命令?

      linux分隔文件命令?,系统,信息,文件,命令,位置,指令,文件夹,目录,前缀,方法,l

      linux改文件权限命令?

      linux改文件权限命令?,系统,工具,档案,权限,文件,信息,命令,目录,选项,用户,

      linux命令交换文件名?

      linux命令交换文件名?,命令,文件,数据,名称,工具,地址,软件,系统,基础知识,

      linux文件夹转移命令?

      linux文件夹转移命令?,系统,文件,命令,位置,材料,信息,工具,电脑,目录,源文

      linux转移文件命令?

      linux转移文件命令?,文件,命令,密码,电脑,位置,名称,信息,系统,目录,目标,lin

      linux下替换文件命令?

      linux下替换文件命令?,文件,一致,评论,名称,标的,资料,工作,命令,字符串,内

      linux文件nl命令?

      linux文件nl命令?,地址,工作,信息,系统,情况,标准,实时,对比,百度,命令,linux

      linux寻找文件夹命令?

      linux寻找文件夹命令?,名称,命令,文件,位置,工作,标准,目录,子目录,文件名,

      linux跳到文件尾命令?

      linux跳到文件尾命令?,系统,文件,命令,管理,状态,实时,末尾,光标,内容,编辑,l

      linux把文件复制命令?

      linux把文件复制命令?,名字,文件,软件,系统,位置,目录,命令,源文件,目标,文

      linux文件夹合并命令?

      linux文件夹合并命令?,文件,对比,第一,下来,命令,文件夹,两个,字段,内容,数

      linux下文件创建命令?

      linux下文件创建命令?,名字,名称,首次,命令,文件,系统,密码,文件名,文件夹,

      linux命令行安装文件?

      linux命令行安装文件?,软件,官网,密码,中心,电脑,文件,命令,终端,指令,版本,L

      linux文件解包命令?

      linux文件解包命令?,系统,地址,命令,文件,管理,手机,数据,工具,标准,单位,lin

      linux重启文件命令?

      linux重启文件命令?,系统,工作,标准,设备,命令,灵活,用户,电源,方式,级别,lin

      linux解压文件命令行?

      linux解压文件命令行?,系统,电脑,命令,文件,平台,名称,软件,管理,标准,目录,

      linux文件发送到命令?

      linux文件发送到命令?,服务,软件,系统,数据,文件,命令,工作,第一,工具,服务

      linux命令编辑文件?

      linux命令编辑文件?,系统,状态,电脑,命令,数据,标准,不了,名称,发行,网络,Lin

      linux文件乱码命令?

      linux文件乱码命令?,系统,环境,乱码,信息,状态,盘中,文件,字符集,中文,文件