使用RegEx模式处理点和破折号作为DNS主机名的分隔符



我正在排除一个旧的。net 3.0应用程序,该应用程序读取自由格式文本文件,电子邮件日志,并使用c#解析文本以检索IP地址和/或DNS主机名。这个问题由于我们的其他内部应用施加的约束而变得复杂,这些应用需要在存储在数据库中时对主机名进行特定的格式化。目前,在这个旧的应用程序中,主机名是用点分隔符格式化的,就像IP地址。这需要更新,以允许在主机名上使用破折号作为分隔符,同时保持主机名的域组件用点分隔。最后,主机名的两个副本将被存储,原始的在DNS查询中返回,修改后的版本与现有系统兼容。

更具体地说,我遇到的问题是,当DNS主机名有一个IP地址作为主机名的一部分时,例如"abc121-213-219-33. hostname.some.domain.com",这样的字符串需要像这样格式化,"abc121-213-219-33. hostname.some.domain.com"。

请注意,Host Name上使用的分隔符与域组件上使用的分隔符不同。我想用RegEx来做这件事,并且一直在使用我在这个网站上找到的一个启动器模式,但是我的技能不足以进一步调整这些,假设这是可能的。

我需要的是能够从主机名中获得IP地址,当这是唯一出现IP的地方时,并且我需要强制在完全限定的DNS主机名的主机名组件上使用破破号作为分隔符。

下面的第一个示例可以很好地从主机名中提取IP地址,但只有当IP部分中使用的分隔符是点时才可以。我正在寻找一个正则表达式,拉出的IP,无论点或破折号。此外,当Host Name在八位字节前面有1个或多个alpha字符时,需要在alpha字符和八位字节的第一个数字之间插入破折号。

这是我最后一次尝试,只有当分隔符是点时才能获得IP。

StringBuilder sb = new StringBuilder();
String returnValue = string.Empty;
// String _hostName -> passed  in as a method parameter.
sb.Append("\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.");
sb.Append("(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]");
sb.Append("[0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b");
if (Regex.IsMatch(_hostname, sb.ToString(), RegexOptions.IgnoreCase))
returnValue = Regex.Match(_hostname, sb.ToString(), RegexOptions.IgnoreCase).Value;

上面的RegEx在DNS主机名

上产生这些结果
// Example 1: Input string "a121-213-219-33.hostName.some.domain.com" -> Returns: ""
// Example 2: Input string "121-213-219-33.hostName.some.domain.com" -> Returns: ""
// Example 3: Input string "a121.213.219.33.hostName.some.domain.com" -> Returns: ""
// Example 4: Input string "121.213.219.33.hostName.some.domain.com" -> Returns: "121.213.219.33"
// Example 5: Input string "abc-121-213-219-33.hostName.some.domain.com" -> Returns: ""
// Example 6: Input string "abc.121.213.219.33.hostName.some.domain.com" -> Returns: "121.213.219.33"

对于仅IP地址,这是我试图通过使用RegEx获得的:

// Example 1: Input string "121-213-219-33.hostName.some.domain.com" -> Returns: "121.213.219.33"
// Example 3: Input string "121.213.219.33.hostName.some.domain.com" -> Returns: "121.213.219.33"
// Example 4: Input string "abc-121-213-219-33.hostName.some.domain.com" -> Returns: "121.213.219.33"

主机名更有问题。下一个示例从一行文本中提取整个主机名,但如果八位字节有一个前导alpha字符,并且没有使用破折号分隔符格式化主机名组件,则再次失败。

sb.Append("^(?!.{256})(?:[a-z0-9][a-z0-9-]{0,61}[a-z0-9]\.|[a-z0-9]\.)+(?:[a-z]{2}");
sb.Append("|AERO|ARPA|ASIA|BIZ|CAT|COM|COOP|EDU|GOV|INFO|INT|JOBS|MIL|MOBI|MUSEUM|NAME|NET|ORG|POST|PRO|TEL|TRAVEL|XXX)$");
if (Regex.IsMatch(_hostname, sb.ToString(), RegexOptions.IgnoreCase))
returnValue = Regex.Match(_hostname, sb.ToString(), RegexOptions.IgnoreCase).Value;

// Matches a DNS Host Name
// Example 1: Input string "a121-213-219-33.hostName.some.domain.com" -> Returns: "a121-213-219-33.hostName.some.domain.com"
// Example 2: Input string "121-213-219-33.hostName.some.domain.com" -> Returns: "121-213-219-33.hostName.some.domain.com"
// Example 3: Input string "a121.213.219.33.hostName.some.domain.com" -> Returns: "a121.213.219.33.hostName.some.domain.com"
// Example 4: Input string "121.213.219.33.hostName.some.domain.com" -> Returns: “121.213.219.33.hostName.some.domain.com”
// Example 5: Input string "abc-121-213-219-33.hostName.some.domain.com" -> Returns: "abc-121-213-219-33.hostName.some.domain.com"
// Example 6: Input string "abc.121.213.219.33.hostName.some.domain.com" -> Returns: "abc.121.213.219.33.hostName.some.domain.com"

对于Host Names,我要返回的是这样的,请注意Host Name组件中对分隔符的一致使用:

// Example 1: Input string "a121-213-219-33.hostName.some.domain.com" -> Returns: "a-121-213-219-33-hostName.some.domain.com"
// Example 2: Input string "121-213-219-33.hostName.some.domain.com" -> Returns: "121-213-219-33-hostName.some.domain.com"
// Example 3: Input string "a121.213.219.33.hostName.some.domain.com" -> Returns: "a-121-213-219-33-hostName.some.domain.com"
// Example 4: Input string "121.213.219.33.hostName.some.domain.com" -> Returns: “121-213-219-33-hostName.some.domain.com”
// Example 5: Input string "abc-121-213-219-33.hostName.some.domain.com" -> Returns: "abc-121-213-219-33-hostName.some.domain.com"
// Example 6: Input string "abc.121.213.219.33.hostName.some.domain.com" -> Returns: "abc-121-213-219-33-hostName.some.domain.com"

还要注意,当一个主机名,如"abc121-213-219-33.hostName.some.domain.com", Regex,除了匹配一个有前导字符的八位字节外,还需要在这些字符和IP八位字节的第一个数字之间插入一个破折号。

DB存储的最终格式应该是这样的:

"abc-121-213-219-33-hostName.some.domain.com" or
"121-213-219-33-hostName.some.domain.com" but not like
"abc121-213-219-33-.hostName.some.domain.com" and not like
"abc-121.213.219.33.hostName.some.domain.com"

提前感谢。

不幸的是,你的问题受到了分析瘫痪的影响,因为你过多地提供了。net 3、原始源代码和所有失败....

一个人应该要求的,是一个模式,并显示之前/之后的可能性;只有一个明显的之前,之后的例子。: -/

因此,我将只处理已明确提出的一项。然后你就可以把我写的东西转换成。net 3。


"abc121-213-219-33.hostName.some.domain.com"这样的字符串需要这样格式化,"abc121-213-219-33.hostName.some.domain.com"

这个模式应该处理ip地址和域名问题。

var pattern = @"
^                          # Beginning of the line
(?<IPLetters>[a-zA-Z]+)?  # If letters, then match
(
(?<Octet>d+)           # IP numbers and a
W                     # . or a - (not a word)
){4}                      # 4 of them
(?<Host>.+)                # The rest is the host.
";
// Result:   abc-121-213-219-33-hostName.some.domain.com
var input = "abc121-213-219-33.hostName.some.domain.com";
var match = Regex.Match(input, pattern,
RegexOptions.IgnorePatternWhitespace); // allows pattern commenting

var IPLetters = match.Groups["IPLetters"].Success 
? match.Groups["IPLetters"].Value.ToString() 
: string.Empty;
var IPAddress = string.Join('-', 
match.Groups["Octet"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.ToList());
var host = match.Groups["Host"].Value.ToString();
var hasIPLetters = !string.IsNullOrEmpty(IPLetters);
Console.WriteLine($"{IPLetters}{(hasIPLetters ? "-" : string.Empty)}{IPAddress}-{host}");

上面代码的结果:

abc-121-213-219-33-hostName.some.domain.com


如果移植回V3需要修复什么

  • Var需要被删除
  • 字符串内插更改为string.Format。Linq是在。net 3.5

什么保持不变

  • 字符串
  • 任何正则表达式都是一样的,包括选项。

相关内容

  • 没有找到相关文章

最新更新