循环双引号但忽略单引号中的双引号

Jui*_*icy 3 c# iteration quotes double-quotes

我有我认为是逻辑问题.我在C#编码,但欢迎使用一般的伪代码解决方案.

我有这个文本文件,包含,例如,这个文本:

blah "hello john"
blah 'the code is "flower" '
blah "good night"
Run Code Online (Sandbox Code Playgroud)

我想循环使用双引号并对它们做一些事情,但我想忽略单引号中包含的双引号.我得到开头双引号和结束双引号的位置(string data包含文本文件的内容):

C#

// Start searching from beginning
int quotestart = 0, quoteend = 0;

while (data.IndexOf('"', quotestart) != -1)
{
  // Get opening double quote
  quotestart = data.IndexOf('"', quotestart);
  // Get ending double quote
  quoteend = data.IndexOf('"', quotestart + 1);

  string sub = data.Substring(quotestart + 1, quoteend - quotestart - 1);
  Console.WriteLine(sub);

  // Set the start position for the next round
  quotestart = quoteend + 1;
}
Run Code Online (Sandbox Code Playgroud)

使用我的代码,输出将是:

hello john
flower
good night
Run Code Online (Sandbox Code Playgroud)

因为"花"在单引号内,我希望我的输出为:

hello john
good night
Run Code Online (Sandbox Code Playgroud)

编辑

我目前正在开发一种方法,我首先在单引号之间填充所有数据,例如'A'.这样,当我遍历双引号时,忽略单引号之间的任何数据.不确定这是否是正确的方法.

Eri*_*ert 7

我尝试使用谷歌搜索有限状态机,但没有正式的计算机工程培训,我必须承认我有点迷失.你还有其他指示吗?

FSM是最简单的计算机形式之一.这个想法是你有一定数量的"状态"信息和稳定的输入流.每个输入使得状态以可预测的方式改变,仅基于当前状态和当前输入,并且导致可预测的输出发生.

因此,假设您的输入是单个字符,输出是单个字符或"空"字符.这是一个做你想要的FSM:

  • 国家是OUTSIDE,INSIDEDOUBLEINSIDESINGLE.
  • 输入是",'x.(WOLOG x代表任何其他角色.)

我们有三个状态和三个输入,因此有九种可能的组合.

  • 如果我们是,OUTSIDE并得到x,留下OUTSIDE并发出null.
  • 如果我们是,OUTSIDE并得到",去INSIDEDOUBLE和发射null.
  • 如果我们是,OUTSIDE并得到',去INSIDESINGLE和发射null.
  • 如果我们是,INSIDEDOUBLE并得到x,留下INSIDEDOUBLE并发出x
  • 如果我们是,INSIDEDOUBLE并得到",去OUTSIDE和发射null
  • 如果我们是,INSIDEDOUBLE并得到',留下INSIDEDOUBLE并发出'
  • 如果我们是,INSIDESINGLE并得到x,留下INSIDESINGLE并发出null
  • 如果我们是,INSIDESINGLE并得到",留下INSIDESINGLE并发出null
  • 如果我们是,INSIDESINGLE并得到',去OUTSIDE和发射null

唯一剩下的就是说开始状态是OUTSIDE.

所以我们假设输入是1 " 2 " 3 ' 4 " 5 " ' 6.州和产出是:

  • OUTSIDE得到1,发出null,留下来OUTSIDE.
  • OUTSIDE得到",发出null,去INSIDEDOUBLE.
  • INSIDEDOUBLE得到2,发出2,留下来INSIDEDOUBLE
  • INSIDEDOUBLE得到",发出null,去OUTSIDE.
  • OUTSIDE得到3,发出null,留下来OUTSIDE.
  • OUTSIDE得到',发出null,去INSIDESINGLE

...自己填写其余的.

这是否足以让您编写代码?


Eri*_*ert 5

好的解决方案 使用switch语句是为小型FSM执行此操作的传统方法,但是当状态和输入的数量变得庞大且复杂时,它变得难以处理.这是一个更容易扩展的替代解决方案:表驱动的解决方案.也就是说,将有关转换和动作的事实放入数组中,然后FSM只不过是一系列数组查找:

// States
const int Outside = 0;
const int InDouble = 1;
const int InSingle = 2;

// Inputs
const int Other = 0;
const int DoubleQuote = 1;
const int SingleQuote = 2;

static readonly int[,] stateTransitions =
{   /*               Other     DoubleQ   SingleQ */
    /* Outside */  { Outside,  InDouble, InSingle },
    /* InDouble */ { InDouble, Outside,  InDouble },
    /* InSingle */ { InSingle, InSingle, Outside }
};

// Do we emit the character or ignore it?
static readonly bool[,] actions =
{   /*              Other   DoubleQ SingleQ */
    /* Outside */ { false,  false,  false },
    /* InDouble */{ true,   false,  true  },
    /* InSingle */{ false,  false,  false }
};

static int Classify(char c)
{
    switch (c)
    {
        case '\'': return SingleQuote;
        case '\"': return DoubleQuote;
        default: return Other;
    }
}

static IEnumerable<char> FSM(IEnumerable<char> inputs)
{
    int state = Outside;
    foreach (char input in inputs)
    {
        int kind = Classify(input);
        if (actions[state, kind]) 
            yield return input;
        state = stateTransitions[state, kind];
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以得到结果

string.Join("", FSM(@"1""2'3""4""5'6""7'8""9""A'B"))
Run Code Online (Sandbox Code Playgroud)