【问题标题】:Regexp puzzle : encapsulated structures正则表达式难题:封装结构
【发布时间】:2017-06-20 11:55:36
【问题描述】:

所以我在这里尝试做一些所有程序员可能有一天也必须做的事情。

我的代码中有所有这些嵌套的宏,我想在每个 #endif 旁边添加注释,如果它关闭的话 - 如果还没有注释。正则表达式可以为我做到这一点吗?直到现在 * 和 + 在 Notepad++ 中都太贪心了,即使我用的是理论上懒惰的版本 *?和+? ...

例如这个

#if A

Code

#if B

Code

#if C

Code

#endif

Code

#endif /* B */

Code

#endif

进入这个

#if A

Code

#if B

Code

#if C

Code

#endif /* C */

Code

#endif /* B */

Code

#endif /* A */

【问题讨论】:

  • 正则表达式无法处理嵌套结构。即使有回溯扩展,我也不确定这是否可行。
  • 一般来说不可能,因为这不是regular language。证明它的一种方法是,在一般情况下,您无法用有限数量的状态解析它。
  • 如果您使用的是 Notepad++,为什么不用 Notepad++ 标记呢? NPP 正则表达式风格是 Boost,它可以处理递归。
  • 因此,正则表达式不是解决方案,但可以通过简单的perl 脚本(甚至一些 C 代码)来解决。 -- @WiktorStribiżew 有趣的功能,虽然这不再是“常规”;)
  • 这样的 Vim 宏::set nowrapscan^M1GO?^#if^V^M3l"ay$%:s,endif.*$,endif /*^V^Ra */,^V^M%@b^[0"by$ddG@b 只需将其拉入缓冲区并执行即可。 ^V, ^M, ^R 和 ^[ 是 ctrl-那个字符

标签: c regex macros preprocessor


【解决方案1】:

这可以用一个正则表达式来完成吗?见鬼!

这可以在 Notepad++ 中使用 only 正则表达式来完成吗? 该死的!!!

  1. 关闭. matches newline
  2. 将所有\r\n 替换为\n。这使得 Windows 上的正则表达式更加简单。如果需要,您可以稍后将它们改回来。

  3. 通过将^#endif.* 替换为#endif 来清除所有现有的#endif 标记。

  4. 我们只需要关注#if...#endif 行,因此我们通过将^(?!#(if|endif)).* 替换为;$0 来忽略所有其他行。所以; 是我们的“忽略”标记。

  5. 接下来,我们反复更改 #if - #endif 对,它们之间只有被忽略的行。
    所以,反复“全部替换”
    ^#if(.+)\n((;.*\n)*)#endif
    with
    ;#if$1\n$2;#endif /* $1 */ .

    这会将评论应用于所有 #if - #endifs 位于最低嵌套级别,然后用; 标记它们,因此下次单击“全部替换”时,它们将被忽略。
  6. 完成后,通过将^;(.+?\n) 替换为$1 来移除忽略标记。

瞧!

【讨论】:

  • 啊!没有想过反复使用查找/替换,一路修改东西。这种思维方式在未来肯定会有用!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 2015-06-06
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多