hosts文件的正则表达式表现不同

时间:2016-12-19 10:21:58

标签: regex powershell

我想从PowerShell脚本解析我的主机文件。

我观察到不同的行为:

  1. 设置:

    $hostsFile = "$env:windir\System32\drivers\etc\hosts"
    $hostsRegex = '^\s*(?<Address>[0-9\.\:]+)\s+(?<Host>[\w\.\-]+)\s*$'
    
    $entries = Get-Content $hostsFile -Encoding Ascii
    
  2. 使用-match

    $entries -match $hostsRegex
    

    它的行为符合预期,并输出我的所有条目(只有我的条目)。

  3. 使用.Net Regex.Matches方法:

    [Regex]::Matches($entries, $hostsRegex)
    

    未返回任何内容(也尝试使用MultilineSingleLine等选项...

  4. 我的目标是获取自定义PS对象,以便进一步处理。其实我希望这个有效:

    function Get-HostsEntries{
        $hostsFile = "$env:windir\System32\drivers\etc\hosts"
        $hostsRegex = '^\s*(?<Address>[0-9\.\:]+)\s+(?<Host>[\w\.\-]+)\s*$'
    
        $entries = Get-Content $hostsFile -Encoding Ascii
    
        [Regex]::Matches($entries, $hostsRegex ) | %{
            New-Object PSObject -Property @{
                Address = $_.Groups["Address"].Value
                Host = $_.Groups["Host"].Value
            }
        }
    }
    
    Get-HostsEntries
    

    但没有任何回报。

    所以我的问题是:

    1. 为什么PowerShell和.Net调用的行为方式不一样?
    2. 如何修复我的脚本按预期工作?

1 个答案:

答案 0 :(得分:4)

使用-Raw将文件读入单个字符串。否则Get-Content会为您提供[Regex]::Matches无法处理的字符串列表。

$hostsFile = "$env:windir\System32\drivers\etc\hosts"
$entries = Get-Content $hostsFile -Encoding Ascii -Raw

$hostsRegex = [Regex]'(?m)^\s*(?<Address>[0-9.:]+)\s+(?<Host>[\w.-]+)'
$hostsRegex.Matches($entries)

对我来说很好。

请注意正则表达式中的(?m)多线修改器。此外,没有必要在字符类中转义.:-

最后我将表达式直接投射到[Regex],从而无需在以后跳过“静态方法”箍。