用于获取字符串的较短语法? [选择字符串]

时间:2013-11-12 05:50:47

标签: powershell

我在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}每次我只想抓取一个特定的字符串。

3 个答案:

答案 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+"