Powershell 正则表达式 gis 标志支持
Powershell regex gis flags support
我想在使用 gis 标志的 Powershell 中使用这个正则表达式,
https://regex101.com/r/yoM4cV/1
/(?<=#start)(.+)(?=#end)/gis
匹配#start 和#end 之间的句子
#start
hello powershell regex
what is the equivalent of flags gis
#end
我找不到任何关于 Powershell 的 gis 标志支持的信息。 Powershell 中缺少这个吗?如果是,还有什么选择?
更新:我问是因为这个 returns false
$test=@'
#start
hello powershell regex
what is the equivalent of flags gis
#end
'@
$test -match (?<=#start)(.+)(?=#end)
PowerShell 中的正则表达式是用字符串文字定义的,而不是正则表达式文字(类似于 action/pattern/flags
的结构)。
g
标志在 PowerShell 中未作为正则表达式选项实现,您需要使用多重匹配。如果您使用 Select-String
,您将需要 -AllMatches
选项来匹配所有匹配项。如果您使用 .NET 正则表达式 API,ypu 可以使用 Regex.Matches
方法查找所有匹配项。
i
和 s
标志使用更简单,您可以将它们用作内联修饰符,(?s)
、(?i)
,或连接为 (?si)
,您可以将它们放在图案的开头,以便它们可以影响整个图案(或将它们放在图案中的任何位置,以便影响它们右侧的所有图案(并且您可以使用 [=23= 禁用它们]/(?-i)
/(?-si)
)).
如果定义正则表达式对象,可以使用[Text.RegularExpressions.RegexOptions]'Singleline'
、[Text.RegularExpressions.RegexOptions]'IgnoreCase'
或[Text.RegularExpressions.RegexOptions]'IgnoreCase, Singleline'
.
当您需要使用 s
标志时,您必须确保您的输入被视为单个多行字符串。如果你读入文件,你需要确保你使用 -Raw
选项和 Get-Content
.
这是 PowerShell 中 gis
标志“转换”的示例:
$rx = [System.Text.RegularExpressions.Regex]::new('(?<=#start)(.*?)(?=#end)', [Text.RegularExpressions.RegexOptions]'IgnoreCase, Singleline')
$test=@'
#start
hello powershell regex
what is the equivalent of flags gis
#end
'@
$rx.Matches($test).value
输出:
hello powershell regex
what is the equivalent of flags gis
用
可以获得相同的结果
($test | Select-String -Pattern '(?si)(?<=#start)(.*?)(?=#end)' -AllMatches).Matches.Value
要修正你的例子,你需要这样写:
$test -match '(?s)(?<=#start)(.+)(?=#end)'
- 启用 single-line 模式
(?s)
以允许 .
匹配多行。
- 引用正则表达式,因为
()
是 PowerShell 分组运算符,在您的示例中,它使 PowerShell 尝试将正则表达式模式解释为 PowerShell 表达式,但这是行不通的。相反,将其作为文字字符串传递给 -match
.
详细解释:
从gis
开始,只有i
(case-insensitive)和s
(single-line) 在 PowerShell 中作为标志可用(或更普遍地在 .NET 中,因为 PowerShell 在底层使用 .NET RegEx 支持)。
您可以在模式的开头将这些指定为 inline flags ...
(?is)(?<=#start)(.+)(?=#end)
... 或使用 Regex
class, which accepts a RegExOptions
参数的 options
参数:
$options = [System.Text.RegularExpressions.RegexOptions] 'IgnoreCase, Singleline'
[Regex]::Match('text', 'pattern', $options)
g
(全局)标志不能直接使用。您可以通过调用 [Regex]::Matches()
method, which finds all matches (contrary to [Regex]::Match()
和仅找到第一个匹配项的 -match
运算符来有效地使用它)。它的输出是已找到的所有匹配项的集合。
或者,您可以使用带有参数 -AllMatches
的 Select-String
,如 所示。
出于演示目的,我稍微修改了您的示例,以便它实际上找到了多个匹配项(您的原始 RegEx 匹配第一个 #start
到最后一个 #end
之间的所有内容,因此它只会找到一个匹配项).
$text = @'
#start
hello powershell regex
what is the equivalent of flags gis
#end
#start
foobar
#end
'@
$pattern = '(?is)(?<=#start)(.+?)(?=#end)'
foreach( $match in [Regex]::Matches($text, $pattern) ) {
'----- Match -----'
$match.Groups[1].Value # Output the captured value of the 1st group
}
输出:
----- Match -----
hello powershell regex
what is the equivalent of flags gis
----- Match -----
foobar
我想在使用 gis 标志的 Powershell 中使用这个正则表达式,
https://regex101.com/r/yoM4cV/1
/(?<=#start)(.+)(?=#end)/gis
匹配#start 和#end 之间的句子
#start
hello powershell regex
what is the equivalent of flags gis
#end
我找不到任何关于 Powershell 的 gis 标志支持的信息。 Powershell 中缺少这个吗?如果是,还有什么选择?
更新:我问是因为这个 returns false
$test=@'
#start
hello powershell regex
what is the equivalent of flags gis
#end
'@
$test -match (?<=#start)(.+)(?=#end)
PowerShell 中的正则表达式是用字符串文字定义的,而不是正则表达式文字(类似于 action/pattern/flags
的结构)。
g
标志在 PowerShell 中未作为正则表达式选项实现,您需要使用多重匹配。如果您使用 Select-String
,您将需要 -AllMatches
选项来匹配所有匹配项。如果您使用 .NET 正则表达式 API,ypu 可以使用 Regex.Matches
方法查找所有匹配项。
i
和 s
标志使用更简单,您可以将它们用作内联修饰符,(?s)
、(?i)
,或连接为 (?si)
,您可以将它们放在图案的开头,以便它们可以影响整个图案(或将它们放在图案中的任何位置,以便影响它们右侧的所有图案(并且您可以使用 [=23= 禁用它们]/(?-i)
/(?-si)
)).
如果定义正则表达式对象,可以使用[Text.RegularExpressions.RegexOptions]'Singleline'
、[Text.RegularExpressions.RegexOptions]'IgnoreCase'
或[Text.RegularExpressions.RegexOptions]'IgnoreCase, Singleline'
.
当您需要使用 s
标志时,您必须确保您的输入被视为单个多行字符串。如果你读入文件,你需要确保你使用 -Raw
选项和 Get-Content
.
这是 PowerShell 中 gis
标志“转换”的示例:
$rx = [System.Text.RegularExpressions.Regex]::new('(?<=#start)(.*?)(?=#end)', [Text.RegularExpressions.RegexOptions]'IgnoreCase, Singleline')
$test=@'
#start
hello powershell regex
what is the equivalent of flags gis
#end
'@
$rx.Matches($test).value
输出:
hello powershell regex
what is the equivalent of flags gis
用
可以获得相同的结果($test | Select-String -Pattern '(?si)(?<=#start)(.*?)(?=#end)' -AllMatches).Matches.Value
要修正你的例子,你需要这样写:
$test -match '(?s)(?<=#start)(.+)(?=#end)'
- 启用 single-line 模式
(?s)
以允许.
匹配多行。 - 引用正则表达式,因为
()
是 PowerShell 分组运算符,在您的示例中,它使 PowerShell 尝试将正则表达式模式解释为 PowerShell 表达式,但这是行不通的。相反,将其作为文字字符串传递给-match
.
详细解释:
从gis
开始,只有i
(case-insensitive)和s
(single-line) 在 PowerShell 中作为标志可用(或更普遍地在 .NET 中,因为 PowerShell 在底层使用 .NET RegEx 支持)。
您可以在模式的开头将这些指定为 inline flags ...
(?is)(?<=#start)(.+)(?=#end)
... 或使用 Regex
class, which accepts a RegExOptions
参数的 options
参数:
$options = [System.Text.RegularExpressions.RegexOptions] 'IgnoreCase, Singleline'
[Regex]::Match('text', 'pattern', $options)
g
(全局)标志不能直接使用。您可以通过调用 [Regex]::Matches()
method, which finds all matches (contrary to [Regex]::Match()
和仅找到第一个匹配项的 -match
运算符来有效地使用它)。它的输出是已找到的所有匹配项的集合。
或者,您可以使用带有参数 -AllMatches
的 Select-String
,如
出于演示目的,我稍微修改了您的示例,以便它实际上找到了多个匹配项(您的原始 RegEx 匹配第一个 #start
到最后一个 #end
之间的所有内容,因此它只会找到一个匹配项).
$text = @'
#start
hello powershell regex
what is the equivalent of flags gis
#end
#start
foobar
#end
'@
$pattern = '(?is)(?<=#start)(.+?)(?=#end)'
foreach( $match in [Regex]::Matches($text, $pattern) ) {
'----- Match -----'
$match.Groups[1].Value # Output the captured value of the 1st group
}
输出:
----- Match -----
hello powershell regex
what is the equivalent of flags gis
----- Match -----
foobar