C# - Извлечение спутника двух линейных элементов из текстового файла
Я очень новичок в C# и программировании в целом, поэтому я прошу прощения, если это не имеет смысла... Мне нужно иметь возможность искать текстовое поле или комбинированный список, чтобы прочитать файл блокнота, содержащий много спутниковых двухстрочных кодов. Текстовый файл изложен так:
0 VANGUARD 1
1 00005U 58002B 14242.42781498 .00000028 00000-0 24556-4 0 2568
2 00005 034.2497 271.4959 1848458 183.2227 175.4750 10.84383299975339
0 TRANSIT 2A
1 00045U 60007A 14245.43855606 .00000265 00000-0 95096-4 0 2208
2 00045 066.6958 193.0879 0251338 053.7315 060.2264 14.33038972819563
0 EXPLORER 11
1 00107U 61013A 14245.36883128 .00001088 00000-0 12832-3 0 1217
2 00107 028.7916 229.2883 0562255 219.9933 302.0575 14.05099145667434
И т.п.
Мне нужно найти в поле имя единственного спутника (имя после 0 в первой строке) и извлечь это имя в другое текстовое поле и использовать в моем коде. Кроме того, мне нужно отдельно извлечь две строки кода непосредственно под именем, выбранным в поле (также для использования в коде).
Я написал код для использования этих двух строковых элементов, но я не могу автоматически вставить их в свой код.
Спасибо
3 ответа
Вы можете использовать регулярные выражения для этой задачи.
(Я предполагаю, что блок букв / цифр после имени также является частью имени)
Этот код будет делать следующее:
- захватить название спутника и две линии в
Satellite
объект - заполнить ComboBox с именами спутников
- всякий раз, когда вы выбрали спутник, вы можете знать, какой он был
- окно поиска, которое ищет первый спутник, начинающийся с напечатанного текста
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private readonly BindingList<Satellite> _satellites = new BindingList<Satellite>();
private string _input = @"
0 VANGUARD 1
1 00005U 58002B 14242.42781498 .00000028 00000-0 24556-4 0 2568
2 00005 034.2497 271.4959 1848458 183.2227 175.4750 10.84383299975339
0 TRANSIT 2A
1 00045U 60007A 14245.43855606 .00000265 00000-0 95096-4 0 2208
2 00045 066.6958 193.0879 0251338 053.7315 060.2264 14.33038972819563
0 EXPLORER 11
1 00107U 61013A 14245.36883128 .00001088 00000-0 12832-3 0 1217
2 00107 028.7916 229.2883 0562255 219.9933 302.0575 14.05099145667434
";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var regexObj =
new Regex(@"(?<=^\d+\s(?<name>[\w|\d|\s]+))\r\n(?<line1>(?<=^).*)\r\n(?<line2>(?<=^).*(?=\r))",
RegexOptions.Multiline);
Match matchResult = regexObj.Match(_input);
while (matchResult.Success)
{
string name = matchResult.Groups["name"].Value;
string line1 = matchResult.Groups["line1"].Value;
string line2 = matchResult.Groups["line2"].Value;
var regexObj1 = new Regex(@"(?<=^[1|2].*)([\d\w.-]+)");
Match matchResult1 = regexObj1.Match(line1);
var numbers1 = new List<string>();
while (matchResult1.Success)
{
string s = matchResult1.Value;
numbers1.Add(s);
matchResult1 = matchResult1.NextMatch();
}
var regexObj2 = new Regex(@"(?<=^[1|2].*)([\d\w.-]+)");
Match matchResult2 = regexObj2.Match(line2);
var numbers2 = new List<string>();
while (matchResult2.Success)
{
string s = matchResult2.Value;
numbers2.Add(s);
matchResult2 = matchResult2.NextMatch();
}
_satellites.Add(new Satellite
{
Name = name,
Line1 = line1,
Line2 = line2,
Numbers1 = numbers1,
Numbers2 = numbers2
});
matchResult = matchResult.NextMatch();
}
comboBox1.DataSource = _satellites;
comboBox1.DisplayMember = "Name";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var comboBox = (ComboBox) sender;
var satellites = comboBox.DataSource as List<Satellite>;
if (satellites != null && comboBox.SelectedIndex > -1)
{
Satellite selectedSatellite = satellites[comboBox.SelectedIndex];
Console.WriteLine("Selected satellite: " + selectedSatellite.Name);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
var textBox = (TextBox) sender;
string text = textBox.Text;
if (!string.IsNullOrWhiteSpace(text))
{
Satellite satellite =
_satellites.FirstOrDefault((s => s.Name.ToLower().StartsWith(text.ToLower())));
if (satellite != null)
{
Console.WriteLine("Found satellite: " + satellite);
}
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
var textBox = (TextBox) sender;
string text = textBox.Text;
if (!string.IsNullOrWhiteSpace(text))
{
Satellite satellite =
_satellites.FirstOrDefault(
s => s.Numbers1.Any(t => t.StartsWith(text)) || s.Numbers2.Any(t => t.StartsWith(text)));
if (satellite != null)
{
Console.WriteLine("Found satellite: " + satellite);
}
}
}
}
internal class Satellite
{
public string Name { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public List<string> Numbers1 { get; set; }
public List<string> Numbers2 { get; set; }
public override string ToString()
{
return string.Format("Name: {0}", Name);
}
}
}
Результат:
Вот что вы можете попробовать быстро и грязно, что я придумал.
Поместите файл в папку на локальном жестком диске.
Во-вторых, где я определил путь к файлу, замените его на ваш фактический путь к файлу и узнайте, как использовать символ @ и что он означает в C#
3-е замечание, как я использовал строку. Замените метод. Вам придется настроить его. Я только что дал вам идею. Я не собираюсь писать весь код для вас... удачи.
static void Main(string[] args)
{
var fileName = string.Empty;
var filePath = @"C:\Users\myfolder\Documents\RGReports\"; //for testing purposes only
List<string> listNames = new List<string>();
string[] filePaths = Directory.GetFiles(@filePath);
foreach (string file in filePaths)
{
if (file.Contains(".txt"))
{
fileName = file;
using (StreamReader sr = File.OpenText(fileName))
{
//string s = String.Empty;
var tempFile = sr.ReadToEnd();
var splitFile = tempFile.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
foreach (string str in splitFile)
{
if (str.Length == 12)
{
listNames.Add(str.Substring(0, str.Length).Replace("0", "").Replace("1", "").Replace("2A",""));
}
Console.WriteLine(str);
}
}
}
}
}
Результаты приведут к следующему для имен, например, протестированных в консольном приложении
АВАНГАРД
TRANSIT
EXPLORER
Если вы не хотите использовать регулярные выражения, вы можете сделать что-то вроде этого:
public List<string> GetSatelliteNames(string input)
{
string[] split = input.split(new string[2] { "\n", "\r\n" });
List<string> result = new List<string>();
foreach (var s in split)
{
string splitagain = s.split(new char[1] { ' ' });
if (s[0] == "0") result.add(s[1]);
}
return result;
}