【问题标题】:Why doesn't powershell regex work with \n?为什么 powershell 正则表达式不能与 \n 一起使用?
【发布时间】:2020-07-06 07:52:03
【问题描述】:

我有一个包含数千行的文本文件,看起来像这样:

# RandomLocation.xaml:1234
msgid "RandomString"
msgstr ""

# AnotherLocation.cs:123
msgstr ""

我需要找到并删除其中没有 msgid 的每个块,我正在尝试使用正则表达式来完成。

$temp | ForEach-Object{
    Select-String -Path $($DestinationPath + $culturename + ".po") -Pattern '#[: ](.)\w+.[cx][sa][m]{0,1}[l]{0,1}:\d+\nmsgstr ".*"' -AllMatches | ForEach-Object {
            $_.Matches | ForEach-Object{
                $temp2 = $_.Value
                $delete.Add($_.Value)
}
}
}

如果我从模式中删除\nmsgstr ".*"',它会正常工作并检测每个# RandomLocation:1234,但是当我试图找到两行时它不起作用。任何想法我做错了什么?

@edit:它可以工作,但是我无法从文件中删除这些行。它是一个数组列表,虽然用$file.Remove($_.Value) 删除单行有效,但当$_.Value 有两行时就不行了。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    Select-String 会将文件分成几行。应用正则表达式时不再有\n

    如果您需要\n 存在,请使用Get-Content -Raw 将文件读入一个大字符串(没有-RawGet-Content将文件分成几行),并且然后将该字符串传递给Select-String

    Get-Content -Path "..." -Raw | Select-String -Pattern "...\n"
    

    话虽如此,你的正则表达式看起来有点可疑

    #[: ](.)\w+.[cx][sa][m]{0,1}[l]{0,1}:\d+\nmsgstr ".*"
    
    • [m]m一样,字符类[]对单个字母没有影响
    • {0,1}? 相同
    • [cx]"cx",不知道你有没有想过这个
    • . 表示“任何字符”,而不是“点” - 点将是 \.

    如果您的意思是 ".cs.xml.xaml.saml",那么 最好直接写而不是写很复杂。

    #[: ](.)\w+\.(cs|xml|xaml|saml):\d+\nmsgstr ".*"
    

    【讨论】:

    • 我尝试了你的方法,但是它只是跳过了循环并且 $delete 保持为空,就像以前一样。当我将鼠标悬停在 $temp2 上时,它只显示没有 msgstr 的第一行。是的,就是你写的。
    • @Patryk 我没有你的文件,也没有调试过你的正则表达式,我只告诉你为什么带有换行符的正则表达式默认在Select-String 中不匹配的原因。仔细查看您的文件。您很可能拥有\r\n 而不是\n
    • 添加 \r 实际上使这件事起作用。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 2015-04-13
    • 2014-06-01
    • 1970-01-01
    • 2014-12-15
    相关资源
    最近更新 更多