在2个字符串之间提取字符串

时间:2015-11-17 14:20:58

标签: regex powershell

我正在尝试提取位于文件中其他2个字符串之间的字符串 字符串是“USE”和“GO”

这就是我的结果:

$importPath = "SOMEPATH"
$pattern = "(?<=\*\*USE\*\*)[\s\S]*(?=\*\*GO\*\*)"

Get-Content $importPath | Foreach {if ([Regex]::IsMatch($_, $pattern)) { $arr += [Regex]::Match($_, $pattern)}}

$arr 

但执行此操作时,我什么都没得到

示例SQL脚本:

USE FIZNET
GO



DECLARE @Symbol_Type_Id SMALLINT

SELECT @Symbol_Type_Id = Symbol_Type_Id 
FROM dbo.SymbolTypes 
WHERE SymbolType = 'Indices - Asia'

UPDATE dbo.Currencies SET
Symbol_Type_Id = @Symbol_Type_Id
WHERE Currency = 'ASX'

GO

我希望$ arr的值为“FIZNET”

3 个答案:

答案 0 :(得分:1)

您可以使用.*正则表达式匹配所有字符串。例如:

$importPath = "PATHNAME"
$pattern = "USE(.*)GO"

$string = Get-Content $importPath
$result = [regex]::match($string, $pattern).Groups[1].Value
$result

答案 1 :(得分:0)

作为替代方法,这可能有所帮助:

$Result = 'SELECT USE SELECT * FROM MyTable GO OTHER STUFF' -split 'USE|GO' |
    Select-Object -Skip 1 -First 1

# Remove space before and after
$Result.Trim()

输出结果为:

SELECT * FROM MyTable

答案 2 :(得分:0)

这里有改进的余地,因为我们没有样本文件,但你的正则表达式模式似乎可以起到这样的作用。

**USE**AdventureWorks2012**GO**

我怀疑这不是数据文件中的线条外观。可能是分开的?我想向您介绍Select-String以帮助缓解此问题。考虑我从TechNet创建的以下错误sql文件(用于测试)。

USE AdventureWorks2012
GO
DECLARE @MyMsg VARCHAR(50)
SELECT @MyMsg = 'Hello, World.'
GO -- @MyMsg is not valid after this GO ends the batch. Just because.

**USE** AdventureWorks2012;
**GO**
DECLARE @MyMsg VARCHAR(50)
SELECT @MyMsg = 'Hello, World.'

现在,在该文件中,我们有一个带星号的示例和一个没有星号的示例。您的正则表达式期待**所以我已经包含了涵盖这两种方案的解决方案。

# Test with one pattern and comment out the other
$pattern = "(?<=USE\*\*)([\s\S]*?)(?=\*\*GO)"
$pattern = "(?<=USE)([\s\S]*?)(?=GO)"

(Get-Content $path -Raw | Select-String -Pattern $pattern -AllMatches -CaseSensitive).Matches.Value | ForEach-Object{$_.Trim()}

使用与您的文字实际匹配的$pattern。如果它确实跨行传播,这将在我们将文件作为一个字符串读取时起作用(对于大文件来说会很慢)。 -CaseSensitive应该有所帮助,以防文本中有一条评论,例如“因为”。另一个重要的变化是,如果文件中存在多个匹配项,则匹配为 -greedy。

模式应分别返回AdventureWorks2012;AdventureWorks2012

使用样本进行编辑

根据我上面的解释使用以下代码,您可以获得预期的结果。

$pattern = "(?<=USE)([\s\S]*?)(?=GO)"
$arr = (Get-Content $path -Raw | Select-String -Pattern $pattern -AllMatches -CaseSensitive).Matches.Value | ForEach-Object{$_.Trim()}