代码之家  ›  专栏  ›  技术社区  ›  Francesco Mantovani

仅从文件中筛选大写单词

  •  3
  • Francesco Mantovani  · 技术社区  · 6 年前

    SESSIONDAYOFWEEK
    FILMTITLELONGALT
    tblTrans_Ticket.
    ADMITDETAILSALT2
    MESSAGESTUB2ALT3
    StartDayOfWeek
    Description
    MESSAGESTUB2ALT2
    FILMTITLESHORTALT
    Applications
    TICKETTYPELONGALT
    

    我需要过滤那个文件,只选择只有大写字符的单词,然后去掉那些有小写字符的单词。

    Get-Content .\out.txt | ForEach-Object if ($_.IsUpper) {Write-Host $_}
    

    ForEach-Object : Input name "if" cannot be resolved to a method.
    At line:1 char:25
    + ... et-Content .\out.txt | ForEach-Object if ($_.IsUpper) {Write-Host $_}
    +                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (TAIL:PSObject) [ForEach-Object], PSArgumentException
        + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand
    

    我不明白我错在哪里?

    3 回复  |  直到 6 年前
        1
  •  4
  •   Jacob    6 年前

    最简单的方法可能是使用regex。

    Get-Content .\out.txt | Where-Object { $_ -cmatch "\b[A-Z0-9_]+\b" }
    

    Where-Object 充当过滤器,允许任何匹配的内容通过并丢弃任何不匹配的内容。

    -cmatch 将进行区分大小写的正则表达式匹配

    正则表达式解释:

    + 量词在一次和无限次之间匹配,尽可能多地匹配,根据需要回馈(贪婪)

    A-Z 在a(索引65)和Z(索引90)之间的单个字符

    0-9

    _ 与角色匹配 真的吗

    \b

    您可以删除 0-9 如果您不想允许这些字符的单词通过过滤器。

    请参见: https://regex101.com/r/CfgEmU/1

        2
  •  5
  •   mklement0    6 年前

    -cmatch regular expression ):

    Get-Content .\out.txt | Where-Object { $_ -cmatch  '^\p{Lu}+$' }
    
    • -C匹配 是的区分大小写的变体 -match operator -imatch ); 鉴于此 -匹配 不区分大小写,

    • \p{Lu} 匹配单个大写字符-包括重音非ASCII字符,例如 Ü [1] + 匹配一行中的一个或多个。将表达式括在 ^ (字符串开头)和 $

      • Ansgar Wiechers 暗示 -cnotmatch '\p{Ll}' 相反,它的工作原理略有不同:它将消除包含 字符,这意味着即使它们(也)包含非字母字符(只要没有小写字母),也会保留行。

    另一种选择 Select-String 可能表现更好:

    Select-String -CaseSensitive '^\p{Lu}+$' .\out.txt | Select-Object -ExpandProperty Line
    

    选择字符串 默认情况下,too是不区分大小写的(PowerShell通常也是如此),因此
    -CaseSensitive 这里需要开关。

    选择字符串 从PowerShellCore6.1.0开始,不支持直接输出匹配行;相反,它输出匹配信息对象 .Line Select-Object -ExpandProperty Line .
    This GitHub issue 建议添加一个新的开关参数来支持匹配字符串的直接输出。


    至于 你试过什么 :

    要由执行的代码 ForEach-Object cmdlet必须作为 脚本块 -也就是说,一段代码包含在 { ... }

    你忽视了这一点,这导致了你看到的语法错误。

    此外,还有 [string] 类型(.NET字符串)没有 .IsUpper() 方法(即使是这样,您也忘记了 () 之后 .IsUpper ).

    只有 [char] .IsUpper() 方法,即 静止的 一个,你可以这样称呼: [char]::IsUpper('A') -但您必须在循环中为输入字符串中的每个字符调用此方法:

    Get-Content .\out.txt | Where-Object { 
      foreach ($c in $_.ToCharArray()) { if (-not [char]::IsUpper($c)) { return $False } }
      $True
    }
    

    Write-Host 返回 结果 - 写入主机 打印到 -您将无法捕获或重定向此类输出 [2] . 相反,使用 Write-Output 或者,更好的是,依靠PowerShell的 输出行为:简单使用 $_ 作为它自己的语句将输出它-您既不捕获也不重定向的任何表达式或命令都将自动输出(发送到成功输出流)。


    [1] 相比之下,使用字符范围表达式 [A-Z] 只能识别ASCII范围(英文)大写字符。

    [2] 从来没有在PSv4中,但是通过额外的努力,你可以在PSv5+中,但关键是 不是用来输出的 结果 (数据)。

        3
  •  1
  •   Lee_Dailey    6 年前

    你好,弗朗西斯科·曼托瓦尼,

    正如其他人所提到的那样 [string] .IsUpper 财产。这个 [char] 类型具有 .IsUpper() ,但它也缺乏 财产 用那个名字[ 咧嘴笑

    您可以测试所有大写数组项,因此。。。

    $Collection.Where({$_ -ceq $_.ToUpper()})
    

    希望有帮助,