Ответ 1
Я боюсь, что вы должны выполнить замену самостоятельно. Ниже приведен пример кода, который использует state-machine для замены <seg\b[^>*]>
на <seg>
. Единственная проблема, с которой он столкнулся, заключается в том, что если файл заканчивается на <seg attr=""
, то на выход будет записываться только <seg
.
enum TruncateSegState
{
Idle,
TagStart,
TagStartS,
TagStartSE,
TagStartSEG,
TagSEG
}
static void TruncateSeg(StreamReader input, StreamWriter output)
{
TruncateSegState state = TruncateSegState.Idle;
while (!input.EndOfStream)
{
char ch = (char)input.Read();
switch (state)
{
case TruncateSegState.Idle:
if (ch == '<')
state = TruncateSegState.TagStart;
output.Write(ch);
break;
case TruncateSegState.TagStart:
if (ch == 's')
state = TruncateSegState.TagStartS;
else
state = TruncateSegState.Idle;
output.Write(ch);
break;
case TruncateSegState.TagStartS:
if (ch == 'e')
state = TruncateSegState.TagStartSE;
else
state = TruncateSegState.Idle;
output.Write(ch);
break;
case TruncateSegState.TagStartSE:
if (ch == 'g')
state = TruncateSegState.TagStartSEG;
else
state = TruncateSegState.Idle;
output.Write(ch);
break;
case TruncateSegState.TagStartSEG:
if (char.IsWhiteSpace(ch))
state = TruncateSegState.TagSEG;
else
{
state = TruncateSegState.Idle;
output.Write(ch);
}
break;
case TruncateSegState.TagSEG:
if (ch == '>')
{
state = TruncateSegState.Idle;
output.Write(ch);
}
break;
}
}
}
Использование:
using (StreamReader reader = new StreamReader("input.txt"))
using (StreamWriter writer = new StreamWriter("temp.txt"))
TruncateSeg(reader, writer);
После того, как вы сгенерировали temp.txt
, вы используете его как вход для следующего метода, который добавляет отсутствующий тег </seg>
.
enum ReplaceSegTuvState
{
Idle,
InsideSEG
}
static void ReplaceSegTuv(StreamReader input, StreamWriter output)
{
ReplaceSegTuvState state = ReplaceSegTuvState.Idle;
StringBuilder segBuffer = new StringBuilder();
while (!input.EndOfStream)
{
char ch = (char)input.Read();
switch (state)
{
case ReplaceSegTuvState.Idle:
if (ch == '<')
{
char[] buffer = new char[4];
int bufferActualLength = input.ReadBlock(buffer, 0, buffer.Length);
output.Write('<');
output.Write(buffer, 0, bufferActualLength);
if (bufferActualLength == buffer.Length && "seg>".SequenceEqual(buffer))
{
segBuffer.Clear();
state = ReplaceSegTuvState.InsideSEG;
}
}
else
output.Write(ch);
break;
case ReplaceSegTuvState.InsideSEG:
if (ch == '<')
{
char[] buffer = new char[5];
int bufferActualLength = input.ReadBlock(buffer, 0, buffer.Length);
if (bufferActualLength == buffer.Length && "/tuv>".SequenceEqual(buffer))
{
output.Write("</seg>");
output.Write("</tuv>");
state = ReplaceSegTuvState.Idle;
}
else
{
output.Write(segBuffer.ToString());
output.Write('<');
output.Write(buffer, 0, bufferActualLength);
state = ReplaceSegTuvState.Idle;
}
}
else if (!char.IsWhiteSpace(ch))
{
output.Write(segBuffer.ToString());
output.Write(ch);
state = ReplaceSegTuvState.Idle;
}
else
segBuffer.Append(ch);
break;
}
}
}
Использование:
using (StreamReader reader = new StreamReader("temp.txt"))
using (StreamWriter writer = new StreamWriter("output.txt"))
ReplaceSegTuv(reader, writer);