管道分隔和双引号字符串的正则表达式

时间:2014-05-30 14:44:44

标签: c# regex

我有一个像这样的字符串:

"2014-01-23 09:13:45|\"10002112|TR0859657|25-DEC-2013>0000000000000001\"|10002112"

我想通过管道分开用双引号括起来的东西,所以我有类似的东西(类似于csv的完成方式):

[0] => 2014-01-23 09:13:45
[1] => 10002112|TR0859657|25-DEC-2013>0000000000000001
[2] => 10002112

我想知道是否有正则表达式可以做到这一点?

3 个答案:

答案 0 :(得分:2)

我认为您可能需要编写自己的解析器。

哟将需要:

  • 自定义集合以保持结果

  • 布尔标志,用于判断管道是在引号内还是在引号外

  • 字符串(或StringBuilder)以保持当前单词

这个想法是你用char读取字符串char。每个字符都附加在单词上。如果引号外有管道,则将该单词添加到结果集合中。如果有引号,你可以切换一个标志,这样你就不会再将管道当作分隔符,但是你将它作为单词的一部分附加。然后,如果有另一个报价,您再次将标志切换回来。因此,下一个管道将导致将整个单词(带引号内的管道)添加到集合中。我在你的例子中测试了下面的代码并且它有效。

    private static List<string> ParseLine(string yourString)
    {
        bool ignorePipe = false;
        string word = string.Empty;

        List<string> divided = new List<string>();
        foreach (char c in yourString)
        {
            if (c == '|' &&
                !ignorePipe)
            {
                divided.Add(word);
                word = string.Empty;
            }
            else if (c == '"')
            {
                ignorePipe = !ignorePipe;
            }
            else
            {
                word += c;
            }
        }

        divided.Add(word);

        return divided;
    }

答案 1 :(得分:0)

这个正则表达式怎么样:

/((["|]).*\2)/g

<强> Online Demo

看起来它可以用作有效的分割表达式。

答案 2 :(得分:0)

我会公然忽略你想要一个RegEx的事实,因为我认为制作你自己的IEnumerable会更容易。此外,您可以即时访问Linq。

var line = "2014-01-23 09:13:45|\"10002112|TR0859657|25-DEC-2013>0000000000000001\"|10002112";

var data = GetPartsFromLine(line).ToList();


private static IEnumerable<string> GetPartsFromLine(string line)
{
    int position = -1;

    while (position < line.Length)
    {
        position++;

        if (line[position] == '"')
        {
            //go find the next "
            int endQuote = line.IndexOf('"', position + 1);

            yield return line.Substring(position + 1, endQuote - position - 1);

            position = endQuote;

            if (position < line.Length && line[position + 1] == '|')
            {
                position++;
            }
        }
        else
        {
            //go find the next |
            int pipe = line.IndexOf('|', position + 1);

            if (pipe == -1)
            {
                //hit the end of the line
                yield return line.Substring(position);
                position = line.Length;
            }
            else
            {
                yield return line.Substring(position, pipe - position);
                position = pipe;
            }
        }
    }
}

这尚未经过全面测试,但它适用于您的示例。