Регулярные выражения идеально подходят для решения этого типа "проблем". Следующее консольное приложение демонстрирует, как использовать Regex
для извлечения желаемого IP-адреса из целевого строкового блока.
private static readonly string IPV4_PATTERN = "[0-9./]";
private static readonly string IPV4_IPV6_PATTERN = "[A-Z0-9:./]";
static void Main(string[] args)
{
TestSearchFile();
}
private static string ParseIpWithRegex(string textToSearch, string startBlock, string endBlock)
{
var pattern = $@"{startBlock}\D*\s*({IPV4_IPV6_PATTERN}+).*{endBlock}";
var ms = Regex.Match(textToSearch, pattern, RegexOptions.Singleline | RegexOptions.IgnoreCase);
if (ms.Groups.TryGetValue("1", out var g))
{
return g.Value;
}
return string.Empty;
}
private static void TestSearchFile()
{
var sep = Environment.NewLine;
var ipAddress6 = "2001:db8:85a3:8d3:1319:8a2e:370:7348";
var ipAddress4 = "10.4.1.10/32";
var t = "Something here..." + sep;
t += "... ... ... " + sep;
t += "interface \"system\"" + sep;
t += "address " + ipAddress4 + sep;
t += "no shutdown" + sep;
t += "exit" + sep;
t += "something here..." + sep;
t += "address 101.4.1.11/32" + sep;
t += "... ... ... " + sep;
var startBlock = "interface \"system\"";
var endBlock = "exit";
var ip = ParseIpWithRegex(t, startBlock, endBlock);
Console.WriteLine($"IP: {ip}");
}
Я включил два шаблона IP-адресов IPV4_PATTERN
только для IPV4, а также IPV4_IPV6_PATTERN
для IPV4 и IPV6. Выберите тот, который вам больше всего подходит. Хотя IPV4_IPV6_PATTERN
будет применяться к обеим версиям IP, я считаю, что это немного улучшает производительность, когда поиск сужается за счет использования самого узкого шаблона.
Не забудьте импортировать ссылку Regex
:
using System.Text.RegularExpressions;
Код объяснен
Метод «ParseIpWithRegex» использует шаблон Regex
, построенный с использованием строки, обозначающей начало целевой блок и строка, обозначающая конец этого блока. Внутри этого шаблона находится определение класса регулярных выражений, которое определяет шаблон IP-адреса, который мы будем sh изолировать как группу.
$@"{startBlock}\D*\s*({IPV4_IPV6_PATTERN}+).*{endBlock}";
Следует отметить, что фигурные скобки предназначены только для интерполяции строк и не имеют (в данном случае) ничего общего с фактическим регулярным выражением!
После «startBlock» мы видим «\ D *». Это означает, что после «startBlock» включить в поиск все нечисловые c символы (где «звездочка» означает ожидание от нуля до бесконечного числа). Затем мы видим «\ s *», что означает включение всех пробелов (включая символы новой строки, поскольку я включил RegexOptions.Singleline
).
Шаблон IP-адреса заключен в скобки «()», что дает команду Regex
создавать группы. В этом случае за шаблоном IP-адреса (в приведенном выше примере кода IPV4_IPV6_PATTERN
) стоит символ «+». Это указывает на то, что ДОЛЖЕН быть хотя бы один из символов, которые есть в определении класса Regex IP-адреса, чтобы считаться "совпадением".
После этого мы видим ". *" Перед "endBlock". Это означает поиск любого символа - включая символ «новой строки» (от нуля до бесконечного числа) в строке «endBlock».
Если у вас есть какие-либо вопросы, оставьте комментарий.
ИЗМЕНИТЬ
С помощью метода кнопки onclick
вы вызовете SearchFileForIp
. Вам нужно будет изменить myTextBox
в соответствии с вашим кодом.
Вы также должны решить, будете ли вы искать IPV4 или оба IPV4 и IPV6, и выберите соответствующую переменную IPV4_PATTERN
или IPV4_IPV6_PATTERN
.
private void SearchFileForIp()
{
var fileName = "c:\\test.txt";
using var sr = new StreamReader(fileName);
string fileContent = sr.ReadToEnd();
var startBlock = "interface \"system\"";
var endBlock = "exit";
var ip = ParseForIpRegex(fileContent, startBlock, endBlock);
myTextBox.Text = ip; //Change this to match your code
}
private readonly string IPV4_PATTERN = "[0-9./]";
private readonly string IPV4_IPV6_PATTERN = "[A-Z0-9:./]";
private string ParseForIpRegex(string textToSearch, string startBlock, string endBlock)
{
var pattern = $@"{startBlock}\D*\s*({IPV4_PATTERN}+).*{endBlock}";
var ms = Regex.Match(textToSearch, pattern, RegexOptions.Singleline | RegexOptions.IgnoreCase);
if(ms.Groups.Count > 0)
{
return ms.Groups[1].Value;
}
//For .Net Core apps
//if (ms.Groups.TryGetValue("1", out var g))
//{
// return g.Value;
//}
return string.Empty;
}