从字符串前面读取单个int的最简单方法
本文关键字:最简单 方法 int 单个 字符串 前面 读取 | 更新日期: 2023-09-27 18:00:03
我有一个输入字符串,看起来像这样:
4 Bob 32 Joe 64 Sue 123 Bill 42
其中,4表示要跟随的字符串整数对的数量。我目前的处理方式是这样的:
var strings = input.Split(' ');
int count = Int32.Parse(strings[0]);
for ( int i = 0; i < count; i++ )
{
string name = strings[count*2 + 1];
int number = Int32.Parse(strings[count*2 + 1]);
ProcessPerson(name, number);
}
这感觉很麻烦。C#中是否有一些库可以包装字符串并为我提供诸如"readInt"answers"readString"之类的服务。我最终想拥有这样的东西:
int count = input.ReadInt();
for(int i = 0; i<count; i++)
{
ProcessPerson(input.ReadString(), input.ReadInt());
}
在这种情况下,它看起来没有太大的改进,但我的实际对象模型有点复杂。我知道其他语言也有类似的功能,但我不记得有任何.net库可以简单地从字符串的前面读取。
您可以轻松地自己编写这样一个"库":
class Parser
{
private readonly Queue<string> m_parts;
public Parser(string s)
{
m_parts = new Queue<string>(s.Split(' '));
}
public string ReadString()
{
return m_parts.Dequeue();
}
public int ReadInt32()
{
return int.Parse(ReadString());
}
}
如果字符串可能很大,或者你正在从流中读取它,你必须自己进行拆分:
class StreamParser
{
private readonly TextReader m_reader;
public StreamParser(string s)
: this(new StringReader(s))
{}
public StreamParser(TextReader reader)
{
m_reader = reader;
}
public string ReadString()
{
var result = new StringBuilder();
int c = m_reader.Read();
while (c != -1 && (char)c != ' ')
{
result.Append((char)c);
c = m_reader.Read();
}
if (result.Length > 0)
return result.ToString();
return null;
}
public int ReadInt32()
{
return int.Parse(ReadString());
}
}
这可能要好一点:
var strings = input.Split(' ');
for ( int i = 2; i < strings.length; i + 2 )
{
ProcessPerson(strings[i - 1], Int32.Parse(strings[i]));
}
我建议您为此使用正则表达式。这里有一个例子:
string input = "4 Bob 32 Joe 64 Sue 123 Bill";
var matches = Regex.Matches(input, @"(?:('d+) ([a-zA-Z]+))+");
for (int i = 0; i < matches.Count; i++)
{
Console.WriteLine("Number: {0} 't Person: {1}", matches[i].Groups[1], matches[i].Groups[2]);
}
将打印:
人数:4人:Bob人数:32人:Joe电话:64人:苏号码:123人:Bill
使用正则表达式时,您只需要知道如何表达要匹配的模式。在这种情况下,您需要匹配:
[Number][Space][Letters]
一次或多次,对吧?这正是它的意思:('d+) ([a-zA-Z]+)
编辑1:
在这一刻,我真的不知道你是想把每个人之前还是之后的号码联系起来,但你所要做的就是交换上面的模式,所以它会变成:
(?:([a-zA-Z]+) ('d+))+
编辑2:
如果你想跳过第一个数字,你可以使用这个模式:
'd+ (?:([a-zA-Z]+) ('d+))+
所以你匹配的是一个数字('d+
),然后是一个空格(),然后和你之前匹配的一样(CCD_5)
尝试从队列中读取,它可能会更干净:
var s = "4 Bob 32 Joe 64 Sue 123 Bill 42";
var queue = new Queue(s.Split(' '));
var count = Convert.ToInt32(queue.Dequeue());
while (queue.Count != 0)
{
var name = queue.Dequeue();
var number = Convert.ToInt32(queue.Dequeue());
ProcessPerson(name, number);
}
如果将扩展方法添加到Queue,则可以进一步简化(未经测试):
public static class QueueExtensions {
public static int DequeueInt(this Queue<string> queue) {
return Convert.ToInt32(queue.Dequeue());
}
}
ProcessPerson(queue.DequeueInt(), queue.Dequeue());
您还应该在其中添加各种保护,以避免试图将空队列和无效转换出列。