RegEx 仅针对特定嵌套级别删除括号中的文本?
RegEx to delete text in brackets only for specific nested level?
我目前正在努力寻找一个 .NET-RegEx,仅当括号处于嵌套级别 2 时才删除括号中的给定文本。
这里有一个多行的示例字符串来解释问题:
(
(text
(bingo) <-- keep this (level=3)
text)
(text)
(bingo) <-- kick this (level=2)
(text)
)
现在我需要删除级别 2 中的文本“(bingo)”,但不删除任何其他嵌套级别中的文本。
不幸的是,我需要为此使用 .NET RegEx。
任何帮助都非常受欢迎。
你的问题暗示这是一个多行字符串,在这种情况下我建议将它拆分成一个字符串数组,如下所示:
$StringArray = $StringVar -split “`n”
之后您可以遍历此数组并一次处理每一行,如下所示:
ForEach($String in $StringArray) {
$Match = [RegEx]::Match($String, "^ \(.*\)")
if($Match.Success) {
$KeepStrings += $String
}
}
为了编写和理解 RegEx 字符串,我建议使用 https://regex101.com
也许,类似于以下的表达式:
^\s{4}\(bingo\).*\s
替换一个空字符串可能会起作用。
If you wish to explore/simplify/modify the expression, it's been
explained on the top right panel of
regex101.com. If you'd like, you
can also watch in this
link, how it would match
against some sample inputs.
您可以使用跟踪圆括号 (brackets) 嵌套级别的有状态回调来解决此问题:
$txt = @'
(
(text
(bingo)
text)
(text)
(bingo)
(text)
)
'@
$level = 1
[regex]::Replace($txt, '\((bingo\))?|\)', {
param($m) # the match at hand
if ($m.Value -eq ')') { # ')' -> decrease level
([ref] $level).Value--
$m.Value
}
elseif ($m.Groups[1].Value) { # '(bingo)'
if (([ref] $level).Value -eq 2) { # remove
''
} else { # keep
$m.Value
}
}
else { # '(' -> increase level
([ref] $level).Value++
$m.Value
}
})
以上结果:
(
(text
(bingo)
text)
(text)
(text)
)
注:
- 仅匹配完全匹配的字符串
(bingo)
。
- 只有匹配的字符串本身 - 如果在请求的级别 - 被删除(而不是整行)。
我目前正在努力寻找一个 .NET-RegEx,仅当括号处于嵌套级别 2 时才删除括号中的给定文本。
这里有一个多行的示例字符串来解释问题:
(
(text
(bingo) <-- keep this (level=3)
text)
(text)
(bingo) <-- kick this (level=2)
(text)
)
现在我需要删除级别 2 中的文本“(bingo)”,但不删除任何其他嵌套级别中的文本。
不幸的是,我需要为此使用 .NET RegEx。 任何帮助都非常受欢迎。
你的问题暗示这是一个多行字符串,在这种情况下我建议将它拆分成一个字符串数组,如下所示:
$StringArray = $StringVar -split “`n”
之后您可以遍历此数组并一次处理每一行,如下所示:
ForEach($String in $StringArray) {
$Match = [RegEx]::Match($String, "^ \(.*\)")
if($Match.Success) {
$KeepStrings += $String
}
}
为了编写和理解 RegEx 字符串,我建议使用 https://regex101.com
也许,类似于以下的表达式:
^\s{4}\(bingo\).*\s
替换一个空字符串可能会起作用。
If you wish to explore/simplify/modify the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
您可以使用跟踪圆括号 (brackets) 嵌套级别的有状态回调来解决此问题:
$txt = @'
(
(text
(bingo)
text)
(text)
(bingo)
(text)
)
'@
$level = 1
[regex]::Replace($txt, '\((bingo\))?|\)', {
param($m) # the match at hand
if ($m.Value -eq ')') { # ')' -> decrease level
([ref] $level).Value--
$m.Value
}
elseif ($m.Groups[1].Value) { # '(bingo)'
if (([ref] $level).Value -eq 2) { # remove
''
} else { # keep
$m.Value
}
}
else { # '(' -> increase level
([ref] $level).Value++
$m.Value
}
})
以上结果:
(
(text
(bingo)
text)
(text)
(text)
)
注:
- 仅匹配完全匹配的字符串
(bingo)
。 - 只有匹配的字符串本身 - 如果在请求的级别 - 被删除(而不是整行)。