powershell 拆分中的正则表达式
Regular Expressions in powershell split
我需要根据输入将 UNC fqdn 名称剥离为名称或 IP。
我的例子是
\tom.overflow.corp.com
\123.43.234.23.overflow.corp.com
我只想 tom
或 123.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 }
我需要根据输入将 UNC fqdn 名称剥离为名称或 IP。
我的例子是
\tom.overflow.corp.com
\123.43.234.23.overflow.corp.com
我只想 tom
或 123.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 }