【问题标题】:Translating C# regex into Powershell将 C# 正则表达式转换为 Powershell
【发布时间】:2014-03-08 13:21:58
【问题描述】:

我有这个在 C# 上运行良好的正则表达式:

\s*use\s+(.*?)([\r]{0,1}\n)

我曾尝试在 Powershell 上使用它(或类似版本),但它不起作用。 有人可以帮我吗?

一些失败的尝试:

$query = [regex]::Replace($query, "\s*use\s+(.*?)([`r]{0,1}`n)", ("USE [" + $database + "]"), [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline)

$query = [regex]::Replace($query, "\s*use\s+([^`r]{1,}?)([`r])", ("USE [" + $database + "]$2"), [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline)

$query = $query -ireplace "\s*use\s+(.+)([\r]{0,1})", ("USE [" + $database + "]"

一些问题:

  1. 我需要使用`r`n 来获取C# 的\r\n 吗? (我还不熟悉 PowerShell...)

  2. 由于我的第一次尝试似乎是使用 .NET 函数,所以该函数不应该像在 .NET 上一样工作吗? (因为我认为我看到了一些差异,但我无法确定原因 - 是因为转义字符吗?)

  3. 如何将我的第一个正则表达式(如上所示)翻译成 Powershell(使用 [regex]::Replace() 或 -ireplace)?

更新

要测试的数据(我用它来更改 SQL 脚本中的默认数据库):

            CREATE LOGIN [test] WITH PASSWORD=N'j-9sfjhpsojhp', 
            DEFAULT_DATABASE=[test], DEFAULT_LANGUAGE=[us_english], 
            CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
            GO

            USE test
            GO

            /****** Object:  User [test]    Script Date: 10/07/2011 16:39:48 ******/
            GO

            CREATE USER [test] FOR LOGIN [test] WITH DEFAULT_SCHEMA=[dbo]
            GO

使用 C# 工具,我得到了正确的 USE 行(我可以使用这样的东西替换它:$2USE NewDb$2)。

在 Powershell 中使用这个(使用相同的正则表达式)时,它不起作用(我仍然得到 USE test 打印):

$database = "NewDb"
$query = Get-Content '<path to sql file>'
$query = [regex]::Replace($query, '\s*use\s+(.*?)([`r]{0,1}`n)', ("USE [" + $database + "]"), [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline)
$query

更新

一个可行的解决方案:

$database = "NewDb"
$query = (Get-Content '<file path>') -join "`r`n"
$query = [regex]::Replace($query, '^\s*use\s+(.*?)$', ("`nUSE [" + $database + "]`n"), [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline)
$query

但是,换行符仍然不能像在 .NET 版本中那样工作。

【问题讨论】:

    标签: c# regex powershell escaping


    【解决方案1】:

    如果您单引号正则表达式是否有效?在 Powershell 中,最佳做法是单引号字符串文字,并且仅在明确需要可扩展字符串时才使用双引号。

    编辑:

    好的,首先您需要意识到 Get-Content 将返回一个字符串数组(每行一个),而不是单个多行字符串。 -Replace 仍然适用于数组,但您不想在换行符上匹配 - 没有。

    $query_data = @'
    CREATE LOGIN [test] WITH PASSWORD=N'j-9sfjhpsojhp', 
    DEFAULT_DATABASE=[test], DEFAULT_LANGUAGE=[us_english], 
    CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
    GO
    
    USE test
    GO
    
    /****** Object:  User [test]    Script Date: 10/07/2011 16:39:48 ******/
    GO
    
    CREATE USER [test] FOR LOGIN [test] WITH DEFAULT_SCHEMA=[dbo]
    GO
    '@
    $query_data | set-content ./query.txt
    
    $database = "NewDb"
    $query = Get-Content ./query.txt
    $query = $query -replace '^\s*use\s+(.+)',"USE $database"
    $query
    

    生产:

    CREATE LOGIN [test] WITH PASSWORD=N'j-9sfjhpsojhp', 
    DEFAULT_DATABASE=[test], DEFAULT_LANGUAGE=[us_english], 
    CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
    GO
    
    USE NewDb
    GO
    
    /****** Object:  User [test]    Script Date: 10/07/2011 16:39:48 ******/
    GO
    
    CREATE USER [test] FOR LOGIN [test] WITH DEFAULT_SCHEMA=[dbo]
    GO
    

    您可以将代码简化为:

    $database = "NewDb"
    $query = (Get-Content '<path to sql file>') -replace '^\s*use\s+(.+)',"USE $database"
    

    【讨论】:

    • 不!我现在尝试使用 Powershell 转义的单引号,然后使用 C# 转义,但它仍然不起作用。
    • 您能否发布一个正在使用的数据样本、您获得的结果以及您预期的结果?
    • 谢谢!通过合并文件行并稍微修改正则表达式,我得到了它的工作(我在上面发布了最终代码)。但是,我想知道为什么像\r\n 这样的转义字符有问题(即使我将行与-join "\r\n" 合并,它仍然无法与它们一起工作——用引号而不是斜杠)。
    • 返回和换行符在 Powershell 中转义为“rn”(反引号是转义)。在正则表达式中它是“\r”和“\n”,所以你需要加入“rn”,然后在正则表达式中匹配“\r\n”。
    • 谢谢。这样就搞清楚了!我应该想到这一点(我在我的正则表达式中使用反引号而不是反斜杠)。 :)
    猜你喜欢
    • 2011-10-02
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 2011-09-28
    • 2023-04-10
    相关资源
    最近更新 更多