将C#正则表达式翻译成Powershell

时间:2014-03-08 13:21:58

标签: c# regex powershell escaping

我有这个正则表达式适用于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)?

  4. 更新

    要测试的数据(我用它来更改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版本那样有效。

1 个答案:

答案 0 :(得分: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"