代码之家  ›  专栏  ›  技术社区  ›  Matt Warren

匹配(替换)字符串中的文本组

  •  0
  • Matt Warren  · 技术社区  · 14 年前

    我有以下格式的字符串:

    瞎说 IIF((doc.posttypeid==1),(parse(doc.id)>1000),(doc.parentid>1000)) 瞎说

    我想把它转换成:

    瞎说 (doc.posttypeid==1?分析(doc.id)>1000:doc.parentid>1000) 瞎说

    到目前为止,我正在使用以下regex字符串进行匹配

    IIF\((?<one>[^,]*?),\ (?<two>[^,]*?),\ (?<three>[^,]*)\)

    但是我在平衡所有的括号时遇到了问题,有更好的方法吗,或者regex是一个错误的工具吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   psmears Touffy    14 年前

    一般来说,正则表达式不能正确处理平衡括号,因为这样做需要计算嵌套的深度,嵌套的深度可以任意深,并且正则表达式只能存储有限数量的状态(一般来说)。

    也就是说,我假设您所做的更改没有比三个或四个更深的括号嵌套-在这种情况下,这是可能的。以下是如何构建它:

    很容易匹配一个完全没有括号的序列:

    EXPR0:  [^()]*
    

    我们可以使用它创建一个正则表达式,该表达式与括号中的单个非嵌套表达式匹配:

    PAREN1:   \(EXPR0\)
    

    哪个表达式最多包含一级括号?好吧,这只是paren1和非括号字符的混合:

    EXPR1:    (?:PAREN1|EXPR0)*
    

    考虑到这一点,我们当然可以将括号中的平衡表达式与最多一个嵌套级别进行匹配:

    PAREN2:    \(EXPR1\)
    

    我们可以用同样的方法扩展到匹配任何不超过两级()的平衡表达式。

    EXPR2: (?:PAREN2|EXPR0)*
    

    等等:

    PAREN3:    \(EXPR2\)
    EXPR3:     (?:PAREN3|EXPR0)
    PAREN4:    \(EXPR3\)
    ...
    

    然后,您可以使用它来构造您想要做的替换的匹配项-这是沿着以下几行的内容:

    IIF\(?<one>EXPR5),(?<two>EXPR5),(?<three>EXPR5)\)
    

    (实际上,您需要对内容进行调整,使expr5表达式与未附加逗号不匹配,但我希望应该清楚地知道如何执行此操作:)

    当然,值得编写一个简短的一次性程序来生成所需的R.E.,而不是手动构造它!