我在Powershell中使用Select-String进行了大量的正则表达式匹配。
例如,最简单也许是最常见的匹配,IPv4地址:
$regex = \b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
现在,如果我要在一行中说明:
$ output =`
“Blah blah blah,202.100.100.9,你将在这条线的中间匹配IP,
但不在此行,因为'2.a.3.one'不是有效的IPv4地址“
然后我做:
$output | Select-String $regex
它会给我整条线。
我无法真正以原始形式使用它。
但是,如果我使用它:
$output | Select-String $regex | %{$_.Matches} | %{$_.Value}
它只会给我IP地址,这很棒。
有更简单的方法吗?
我宁愿不输出| %{$ .Matches} | %{$ .Value}每次我只想抓取一个特定的字符串。
答案 0 :(得分:3)
如果您更喜欢Select-String而不是-replace运算符(这只是调用[Regex] :: Replace的语法糖),PowerShell V3有一些可以节省一些输入的快捷方式。
首先,Select-String =>有一个别名; SLS。 其次,使用简单的foreach-object脚本块,您可以仅使用属性替换脚本块。
结合这些,你可以使用
$output | sls $regex | % Matches | % Value
为了节省更多的输入,PowerShell可以选项卡完成匹配而不是值。
更少键入的另一个选项是使用属性语法:
($output | sls $regex).Matches.Value
作为奖励,标签完成可以在此示例中完成匹配和值。请注意,第二个示例适用于V2,但仅限于存在单个匹配行。如果有多个匹配的行,只有在V3中才会看到所有结果,如果启用了严格模式,V2将不会显示任何内容或错误。
答案 1 :(得分:1)
试试这个:
$output -replace ".*($regex).*",'$1'
答案 2 :(得分:0)
首先,我要感谢大家的帮助以及他们努力为我解决这个问题的努力。你的所有建议都很好,也很有用。
我有一个想法,我意识到我正在寻找一个不存在的命令,所以我只是为它写了一个函数:
function Regex-Match {
[cmdletbinding()]
param (
[parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false)]$RegexString,
[parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true)]$SearchString
)
$Results = @($SearchString | Select-String -Pattern $RegexString | % {$_.Matches} | % {$_.Value})
Return $Results
}
为了进一步缩短这一点,我可以使用
New-Alias -Name regx -Value Regex-match
示例命令:
"test string" | regx "\w\s\w"
或
Regex-Match -SearchString (gc .\Stuff.txt) -RegexString "\w+"