【问题标题】:RegEx - match delimiters unless within (nested) angle bracketsRegEx - 匹配分隔符,除非在(嵌套)尖括号内
【发布时间】:2012-09-09 19:36:09
【问题描述】:

我正在尝试通过命名空间分隔符 . 拆分以下(Delphi RTTI 输出):

System.Generics.Collections.TEnumerator<Utils.TPair<System.string,System.string>>

正确的拆分应该是[System, Generics, Collections, TEnumerator&lt;Utils.TPair&lt;System.string,System.string&gt;&gt;]

首先我尝试了一个否定的前瞻\.(?!\&lt;*[a-zA-Z0-9_.,]*\&gt;),但这与Utils.TPair 和最左边的System.string 中的句点相匹配。我可能会补充一点,我有点惊讶,它(正确地)匹配Collections.TEnumerator 中的时间段。我想这证明了我对正则表达式语言的掌握。

所以我试着通过这样说:\.(?!\&lt;*[a-zA-Z0-9_.,&lt;&gt;]*\&gt;) 让它变得“更贪婪”,但后来没有找到匹配项。 (我知道这不是正则表达式通常所说的“贪婪”的意思,但我想不出更合适的描述。)

所以我决定重新开始。据我了解,我应该能够使用消极的环视来解决我的问题。特别是:&lt; 之后的任何匹配项都可以有效地被忽略。所以我决定(?&lt;!\&lt;[a-zA-Z0-9_]*)\. 应该解决我的问题。它没有。这可能是由于(许多)否定后向实现不支持可变长度字符串这一事实。 (具体来说,PCRE - 这基本上是 Delphi 使用的,显然支持可变长度的替代。不过,每个替代都必须在执行时固定。)

因此我转向你,社区。

谁能解释一下这个问题,实际上应该很简单?会很棒!

【问题讨论】:

    标签: regex delphi split delimiter


    【解决方案1】:

    试试这个正则表达式:

    \.(?![^.]*[\w_.,]*>)
    

    它的基本意思是:匹配所有. 后面没有.&gt;&lt;&gt; 之前的&lt;&gt;。 它实际上非常仅限于您的示例。

    rubular

    消极的后视可以更好地解决这个任务:

    (?<!<.{0,1000})\.
    

    表示匹配前面没有&lt;的任何.

    我在 java 中试过这个,它可以工作。 Java 不允许有无限的后视,这就是为什么我使用 1000 {0,1000} 而不是 * 的限制。不知道PCRE是否支持。

    【讨论】:

    • 你在开玩笑——那是!完美运行。谢谢莫尔哈!如果我可能会问:你为什么使用否定字符类?我是这样读的:匹配所有句点。但是,如果句点后面跟着一个句点(未指定的次数),然后打开括号未指定次数,然后是字符类未指定次数,最后是右括号。我的阅读有什么问题?
    • 查看我的评论。我还更新了正则表达式。希望我的解释有点道理,并且无论其限制如何,正则表达式都能满足您的需求。
    • 我添加了第二个应该涵盖更多情况的表达式。
    • 感谢 morja,这是有道理的。 :) 我也检查了负面的lookbehind,但得到了关于非固定长度的异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多