【问题标题】:Reading strings from text files using switch -regex returns null element使用 switch -regex 从文本文件中读取字符串返回空元素
【发布时间】:2016-11-10 23:39:04
【问题描述】:

问题:

我的脚本的目的是从两个文本文件中过滤掉姓名和电话号码,并将它们添加到一个哈希表中,其中名称是键,电话号码是值。

我面临的问题是 $name = $_.Current 正在返回 $null,因此我的哈希没有被填充。

谁能告诉我是什么问题?

File1.txt 的内容:

萝莉

东二街 234 号

罗利数控 12345

9199617621

lori@hotmail.com

==================

File2.txt 内容:

罗伯特

第十大道 2531 号

西雅图 WA 93413

2068869421

robert@hotmail.com

示例代码:

$hash = @{}

Switch -regex (Get-content -Path C:\Users\svats\Desktop\Fil*.txt)

{

'^[a-z]+$' { $name = $_.current} 

'^\d{10}'  {   
         $phone = $_.current
         $hash.Add($name,$phone)
         $name=$phone=$null
       }
default
       {
write-host "Nothing matched"
       }

}
$hash

【问题讨论】:

    标签: powershell powershell-ise


    【解决方案1】:

    $_ 中删除current 属性引用:

    $hash = @{}
    
    Switch -regex (Get-content -Path C:\Users\svats\Desktop\Fil*.txt)
    {
        '^[a-z]+$' { 
            $name = $_
        } 
    
        '^\d{10}'  {
            $phone = $_
            $hash.Add($name, $phone)
            $name = $phone = $null
        }
        default {
            Write-Host "Nothing matched"
        }
    
    }
    $hash
    

    【讨论】:

      【解决方案2】:

      Mathias R. Jessen's helpful answer 解释了您的问题并提供了有效的解决方案:
      它是自动变量 $_ / $PSItem 本身包含当前输入对象 (无论它的类型是什么 - 因此$_ / $PSItem 的属性取决于输入对象的特定类型)。


      除此之外,还有可能让代码更简洁、更高效

      # Initialize the output hashtable.
      $hash = @{}
      
      # Create the regex that will be used on each input file's content.
      # (?...) sets options: i ... case-insensitive; m ...  ^ and $ match
      # the beginning and end of every *line*.
      $re = [regex] '(?im)^([a-z]+|\d{10})$'
      
      # Loop over each input file's content (as a whole, thanks to -Raw).
      Get-Content -Raw File*.txt | foreach {
        # Look for name and phone number.
        $matchColl = $re.Matches($_)
        if ($matchColl.Count -eq 2) { # Both found, add hashtable entry.
          $hash.Add($matchColl.Value[0], $matchColl.Value[1])
        } else {
          Write-Host "Nothing matched."
        }
      }
      
      # Output the resulting hashtable.
      $hash
      

      关于.NET [System.Text.RegularExpressions.Regex] 对象(或简称[regex])构造的说明,[regex] '(?im)^([a-z]+|\d{10})$'

      将匹配选项 IgnoreCaseMultiline 作为 inline 选项 im 直接嵌入正则表达式字符串 ((?im) 很方便,因为它允许使用简单的强制转换语法 ([regex] ...) 来构造正则表达式 .NET 对象。

      但是,这种语法可能晦涩难懂,此外,并非所有匹配选项都以内联形式提供,因此这里有更详细但更易于阅读的等效选项:

      $re = New-Object regex -ArgumentList '^([a-z]+|\d{10})$', 'IgnoreCase, Multiline'
      

      请注意,这两个选项必须以逗号分隔,作为 单个 字符串,PowerShell 会将其转换为相应枚举值的位或运算值。

      【讨论】:

      • 感谢 Mkelement 我会尝试运行它。在您的正则表达式中,“im”是什么意思?
      • 它们是匹配选项(具体选项已经在代码 cmets 中进行了解释) - 请参阅 msdn.microsoft.com/en-us/library/yd1hzczs(v=vs.110).aspx 另请参阅我的更新,了解如何更详细地构造正则表达式对象,这更容易理解。
      【解决方案3】:

      其他解决方案,使用 convertfrom-string

       $template=@'
       {name*:Lori}
       {street:234 east 2nd street}
       {city:Raleigh nc 12345}
       {phone:9199617621}
       {mail:lori@hotmail.com}
       {name*:Robert}
       {street:2531 10th Avenue}
       {city:Seattle WA 93413}
       {phone:2068869421}
       {mail:robert@hotmail.com}
       {name*:Robert}
       {street:2531 Avenue}
       {city:Seattle WA 93413}
       {phone:2068869421}
       {mail:robert@hotmail.com}
       '@
      
      
       Get-Content -Path "c:\temp\file*.txt" | ConvertFrom-String -TemplateContent $template | select name, phone
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多