现在我通过帮助解决了这里从两个标签之间获取文本的文本文件,我创建的文本只用了4行进行测试。现在我想创建一个新的文本文件,其中包含原始文件的内容,但是在每个我发现标签之间的文本的地方,我想看空格空字符串。因此,如果原始文本文件现在看起来像这样:
daniel<Text>THISISOUTisthere</Text>
<Text>hellobye</Text>
<Text>danielTHISishereandnotthere</Text>
danie <Text> is THIS here and not THERE</Text>
所以新文件应如下所示:
daniel<Text> </Text>
<Text> </Text>
<Text> </Text>
danie <Text> </Text>
这是现在不起作用的代码。我使用了一些帮助变量,但是在行上运行此代码时出现错误:
string hh = f.Substring(lastIndex, currentIndex);
错误说:索引和长度必须引用字符串中的位置。 参数名称:长度
现在这是完整的代码,不起作用:
private void test()
{
w = new StreamWriter(@"d:\testFile.txt");
int currentLength;
int currentIndex;
int lastIndex = 0;
string startTag = "<Text>";
string endTag = "</Text>";
int startTagWidth = startTag.Length;
//int endTagWidth = endTag.Length;
index = 0;
while (true)
{
index = f.IndexOf(startTag, index);
if (index == -1)
{
break;
}
// else more to do - index now is positioned at first character of startTag
int start = index + startTagWidth;
currentIndex = start;
index = f.IndexOf(endTag, start+1);
if (index == -1)
{
break;
}
// found the endTag
string g = f.Substring(start, index - start - 1);
currentLength = index - start - 1;
string hh = f.Substring(lastIndex, currentIndex);
w.WriteLine(hh);
lastIndex = currentIndex + currentLength;
listBox1.Items.Add(g);
}
}
请帮我这个代码。
答案 0 :(得分:1)
substring将长度作为其第二个参数而不是索引位置,因此它应该是
string hh = f.Substring(lastIndex, currentIndex-lastIndex);
另外,你要删除太多字符,要将currentLength = index - start -1
更改为currentLength = index - start
最后使用Writeline
将是puttin addtional换行符,改为使用Write
。
答案 1 :(得分:1)
对于一个有趣的替代方案,您可以使用正则表达式为您进行替换:
string input = "daniel<Text>THISISOUTisthere</Text>\n<Text>hellobye</Text>\n<Text>danielTHISishereandnotthere</Text>\ndanie <Text> is THIS here and not THERE</Text>";
Regex re = new Regex("(?<=<Text>).*?(?=</Text>)");
string output = re.Replace(input, m => new string(' ', m.Length));
Console.WriteLine(input);
Console.WriteLine();
Console.WriteLine(output);
节目输出:
daniel<Text>THISISOUTisthere</Text>
<Text>hellobye</Text>
<Text>danielTHISishereandnotthere</Text>
danie <Text> is THIS here and not THERE</Text>
daniel<Text> </Text>
<Text> </Text>
<Text> </Text>
danie <Text> </Text>
答案 2 :(得分:0)
另一个有趣的选择,因为我觉得我想尝试让它工作:一个小的自己动手解析器。
注意:到目前为止,这不是真正的HTML或XML解析器!它只会引用一个标记(例如<Text>
)并且只包含任何属性...
那么,解析器需要什么?对,一个标记器。你走了:
static IEnumerable<Token> Tokenize(string input, string tag)
{
int index = 0;
int lastIndex = 0;
// Define the start and end tag and their common first character
char tagChar = '<';
string startTag = tag + '>';
string endTag = '/' + tag + '>';
while (true)
{
Token token = null;
// Search for any new tag token
index = input.IndexOf(tagChar, index) + 1;
if (index <= 0)
break;
// Starttag or endtag token found
if (input.Substring(index, startTag.Length) == startTag)
token = new Token { Start = index - 1, Length = startTag.Length + 1, TypeOfToken = Token.TokenType.StartTag };
else if (input.Substring(index, endTag.Length) == endTag)
token = new Token { Start = index - 1, Length = endTag.Length + 1, TypeOfToken = Token.TokenType.EndTag };
// Yield the text right before the tag and the tag itself
if (token != null)
{
yield return new Token { Start = lastIndex, Length = index - lastIndex - 1, TypeOfToken = Token.TokenType.Text };
yield return token;
lastIndex = index + token.Length - 1;
}
}
// Yield last text token
yield return new Token { Start = lastIndex, Length = input.Length - lastIndex, TypeOfToken = Token.TokenType.Text };
}
class Token
{
public int Start { get; set; }
public int Length { get; set; }
public TokenType TypeOfToken { get; set; }
public enum TokenType
{
Text,
StartTag,
EndTag
}
}
它甚至在某种程度上进行了优化,因为它只搜索<
并检查它是否是之后的开始或结束标记。
将字符串标记化后,剩下的处理非常简单:
static string ProcessString(string input, string tag)
{
var sb = new StringBuilder();
int depth = 0;
foreach (var token in Tokenize(input, tag))
{
// Append all tags, but only text tokens with depth level 0
if (token.TypeOfToken != Token.TokenType.Text ||
(token.TypeOfToken == Token.TokenType.Text && depth == 0))
sb.Append(input.Substring(token.Start, token.Length));
else
sb.Append(new string(' ', token.Length));
// Increment for each starttag, decrement for each endtag, never smaller than 0
depth = Math.Max(0, depth + (token.TypeOfToken == Token.TokenType.StartTag ? 1 :
(token.TypeOfToken == Token.TokenType.EndTag ? -1 : 0)));
}
return sb.ToString();
}
这比正则表达式解决方案更灵活,因为你可以赋予它更多的语义含义,比如深度。比如说:
ProcessString("level0<Tag>level1<Tag>level2</Tag>level1again</Tag>level0again", "Tag");
将被处理为:
"level0<Tag> <Tag> </Tag> </Tag>level0again"