【问题标题】:Remove inner nested string with RegEx使用 RegEx 删除内部嵌套字符串
【发布时间】:2018-04-15 00:43:22
【问题描述】:

我有一个由标记替换形成的字符串,这也会导致部分字符串被标记为删除,例如:

Keep1
{/*DELETE}
Delete1a
    {/*DELETE}
    Delete2
    {DELETE*/}
Delete1b
{DELETE*/}
Keep2
{/*DELETE}
Delete3
{DELETE*/}
Keep3

我是否更正了 RegEx 不能用于仅选择内部 DELETE2 和 DELETE3,删除它们,然后重复获取 DELETE1a/b 直到找不到更多匹配项?

我传递给替换函数的正则表达式是

\{\/\*DELETE\}([\s\S]*?)\{DELETE\*\/\}

这匹配

{/*DELETE}
Delete1a
    {/*DELETE}
    Delete2
    {DELETE*/}

如果这是我可以进行的唯一正则表达式匹配,我可以 [suppress theleading {/*DELETE} and] 递归调用替换函数,我认为这会让我能够移除嵌套的 {TAGS}

有更好的方法吗?

我在 VBScript 中使用 RegEx

编辑:如果有帮助,我可以将{/*DELETE}{DELETE*/} 标签更改为单个字符

EDIT2:我可以使用单个字符作为开始/结束删除标记 - 例如,如果 RegEx 表达式解析速度更快,例如不那么复杂

例如如果 Start-Delete 是 [ 然后 end delete 是 ]

Keep1
[
Delete1a
    [
    Delete2
    ]
Delete1b
]
Keep2
[
Delete3
]
Keep3

在此示例中选择出现的这些字符,实际上它们会出现在我的真实数据中,但我希望我可以选择两个根本不会出现在我的数据中的 ASCII 值。

澄清:{DELETE}标签并不总是单独出现在一行上,所以这种字符串形成方式也会存在

Keep1{/*DELETE}Delete1a
    {/*DELETE}Delete2{DELETE*/}
Delete1b{DELETE*/}Keep2a
Keep2b{/*DELETE}Delete3{DELETE*/}Keep3

或使用单字符删除标签:

Keep1[Delete1a
    [Delete2]
Delete1b]Keep2a
Keep2b[Delete3]Keep3

【问题讨论】:

  • 请澄清一下:你想把Keep1 Keep2 Keep3最后变成三行吗?你是什​​么意思你可以将标签更改为单个字符?对块的开始/结束分隔符使用相同的字符不是一个好主意,最好有一对不同的字符作为分隔符。
  • RegEx 不能用于仅选择内部 DELETE2 和 DELETE3,删除它们,然后重复以获取 DELETE1a/b 直到找不到更多匹配项,我是否正确? i> 这取决于。在某些极端情况下,您可以使其与正则表达式一起使用,但不是一般情况。
  • 我知道您可以在其他语言中使用此正则表达式:({/\*DELETE}(?:.*?(?1).*?|.*?){DELETE\*/}),但我目前无法测试 vbscript。
  • @Wiktor Stribiżew - 我的意思是对开始/结束使用不同的单个字符,例如如果排除单个字符(在 RegEx 中)比尝试排除整个 {TAG} 更容易
  • @Kristen 请添加示例。

标签: regex vbscript nested


【解决方案1】:

多字符分隔符

如果你的分隔符是多字符标签,你可以使用tempered greedy token:

\{\/\*DELETE}((?:(?!\{\/\*DELETE})[\s\S])*?)\{DELETE\*\/}
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

将匹配任何字符,0 次以上,这不是 {/*DELETE} 字符序列的起点。递归运行此正则表达式替换,请参阅 Iteration 1Iteration 2 演示。

注意如果您在 cmets 或字符串文字中有这些分隔符,这将无法正常工作。

为了安全起见,您可以定义分隔标签仅在一行中显示为单个实体:

^\s*\{\/\*DELETE}(\s*(?:\r?\n(?!\s*\{(?:\/\*DELETE|DELETE\*\/)}).*)*)\r?\n\s*\{DELETE\*\/}\s*$

查看Iteration 1Iteration 2 个演示(此处,您需要启用regExp.Multiline = True

单字符分隔符

这是迄今为止最简单的方案 - 您可以使用起始分隔符字符,然后使用否定字符类匹配除起始和结束分隔符字符之外的任何 0+ 字符 - 然后是结束分隔符字符。

如果起始分隔符 char 是 [ 并且结束分隔符 char 是 ],则正则表达式是众所周知的

\[[^\][]*\]

查看正则表达式演示:Iteration 1Iteration 2

请注意,[] 通常是您需要的数据的一部分,因此您可能会想要使用一些更花哨的配对数据,例如 ‎2985 左白括号) 和 (‎2986 右白括号):

\u2985[^\u2985\u2986]*\u2986

another regex demo

【讨论】:

  • @Kristen 我认为您应该使用 来允许数据中出现常用括号。或者检查 Unicode 表以获取更奇怪的东西 :)
  • "全角左白括号" (U+FF5F) - 从来不知道这是一件事,更不用说它的表亲了,比如“左白龟甲括号”!谢谢你,看起来很理想。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 2018-12-17
  • 2021-03-01
  • 2022-08-19
  • 2016-01-19
相关资源
最近更新 更多