问题
我正在尝试在同一regex中匹配PowerShell短划线注释(# ...
),但不匹配内联注释(<# .. #>
)。我怎样才能做到这一点?
目标
匹配
我想匹配PowerShell注释(使用标签注释语法)。所以简单地说,#
之后的所有内容都被注释掉了。我用#(.*$)/gm
。
正则表达式匹配写在括号[..]
:内的测试用例
Write-Host "Hello world" [# comment here]
[# A line with only comment]
Comment without whitespace[#before]
[Comment with whitespace [#after ]
不匹配
然而,我想在这里使用的是对";内联注释语法";。PowerShell中的内联注释看起来像lorem <# inline comment #> ipsus
。
所以我在这里寻找排除:
Write-Host "Hello world" <# inline comment here #>
<# A line with only inline comment #>
Comment without whitespace<#no whitespace#>around
Inline comment <# in middle #> of line
Comment with whitespace #comment with >
Comment with whitespace #comment with <
Comment with whitespace #comment with <# test #>
我尝试了什么
我尝试将[^<>]
用于类似#[^<>](.*[^<>]$)
的情况,但它并不能适用于上面给出的所有情况。
我在regex101上的进展,直到我陷入困境。
为什么
我正在JavaScript/TypeScript运行时中解析PowerShell,以便能够内联它们,以便为社区驱动的开源项目批量运行它们(cmd
)。我知道会有例外(比如里面有破折号的字符串),但我用简单的正则表达式解析来换取健壮性。
谢谢!
我建议在#
字符之前检查<
,并将所有否定的字符类转换为负查找,以避免跨越行边界:
#(?<!<#)(?![<>])(.*)$(?<![<>])
// Or, to also check for #> after <# use
#(?<!<#(?=.*#>))(?![<>])(.*)$(?<![<>])
请参阅regex演示。如果您不想在线路以<
或>
结束时使匹配失败,请删除(?<![<>])
负查找。
详细信息:
#
-一个#
字符(?<!<#)
-当前位置左侧不允许立即使用<#
(请注意,此检查仅在#
之后触发,因此正则表达式引擎可以仅检查#
之后的位置,而不是字符串中的每个位置(具有嵌套先行的(?<!<#(?=.*#>))
先行检查确保匹配的#
不是<#...#>
子字符串的第二个字符)(?![<>])
-紧挨着右边,不能有<
和>
(.*)
-第1组:除换行字符外的任何零个或多个字符,尽可能多$
-字符串末尾(?<![<>])
-在字符串的末尾,不能有<
和>
字符