powershell 拆分中的正则表达式

Regular Expressions in powershell split

我需要根据输入将 UNC fqdn 名称剥离为名称或 IP。

我的例子是

\tom.overflow.corp.com
\123.43.234.23.overflow.corp.com

我只想 tom123.43.234.23

我的数组中有以下代码,它完美地剥离了域名,但我仍然留下 \tom

-Split '\.(?!\d)')[0]

虽然这不是正则表达式,但它确实有效。 [grin] 我怀疑如果您有大量此类项目,那么您将需要一个正则表达式。它们确实比简单的文本运算符更快。

这将去掉开头的 \,然后将域名替换为 .

# fake reading in a text file
#    in real life, use Get-Content
$InStuff = -split @'
\tom.overflow.corp.com
\123.43.234.23.overflow.corp.com
'@

$DomainName = '.overflow.corp.com'

$InStuff.ForEach({
    $_.TrimStart('\').Replace($DomainName, '')
    })

输出...

tom
123.43.234.23

我在偷 Lee_Daileys $InSTuff 但附加一个

$InStuff = -split @'
\tom.overflow.corp.com
\123.43.234.23.overflow.corp.com
'@
$InStuff |ForEach-Object {($_.Trim('\') -split '\.(?!\d{1,3}(\.|$))')[0]}

示例输出:

tom
123.43.234.23

正如您在 RegEx101 上看到的,数字之间的点 匹配

您的正则表达式原则上成功地分离了感兴趣的标记,但它没有考虑输入字符串中的前导 \

您可以使用正则表达式交替 (|) 在开头包含前导 \ 作为 附加 -split 分隔符.

假设在输入的最开始匹配分隔符会创建一个 元素,索引为 0,然后您需要访问索引 1获取感兴趣的子字符串。

简而言之:传递给 -split 的正则表达式应该是 '^\\|\.(?!\d)' 而不是 '\.(?!\d)',用于访问结果数组的索引应该是 [1] 而不是[0]:

'\tom.overflow.corp.com', '\123.43.234.23.overflow.corp.com' | 
  ForEach-Object { ($_ -Split '^\\|\.(?!\d)')[1] }

以上结果:

tom
123.43.234.23

或者,您可以在单独的步骤中删除前导\,使用-replace

'\tom.overflow.corp.com', '\123.43.234.23.overflow.corp.com' | 
  ForEach-Object { ($_ -Split '\.(?!\d)')[0] -replace '^\\' }

然而 另一种选择 是使用 单个 -replace 操作不需要ForEach-Object 调用(不需要显式迭代):

'\tom.overflow.corp.com', '\123.43.234.23.overflow.corp.com' -replace
  '?(x) ^\\ (.+?) \.\D .+', ''
  • 内联选项 (?x) (IgnoreWhiteSpace) 允许您使用无关紧要的空格使正则表达式更具可读性:任何 未转义的 空格都可以用于视觉格式化。

  • ^\\ 在每个字符串的开头 (^) 匹配 \(用 \ 转义)。

  • (.+?) 延迟匹配一个或多个字符。

  • \.\D 匹配文字 . 后跟 other 而不是数字(\d 匹配数字, \D 是它的否定)。

  • .+ 匹配一个或多个剩余字符,即输入的其余部分。

  • </code> 作为替换操作数指的是正则表达式中第一个捕获组 (<code>(...)) 匹配的内容,并且鉴于正则表达式旨在消耗整个字符串,用它替换它。

Select-String 函数使用正则表达式并用匹配项填充 MatchInfo 对象(然后可以查询)。

正则表达式 "(\.?\d+)+|\w+" 适用于您的特定示例。

"\tom.overflow.corp.com", "\123.43.234.23.overflow.corp.com" |
  Select-String "(\.?\d+)+|\w+" | % { $_.Matches.Value }