【问题标题】:Regex: match, but not if in a comment正则表达式:匹配,但如果在评论中则不匹配
【发布时间】:2011-10-09 23:44:48
【问题描述】:

我有一个数据字段文件,其中可能包含 cmets,如下所示:

id, data, data, data
101 a, b, c
102 d, e, f
103 g, h, i // has to do with 101 a, b, c
104 j, k, l
//105 m, n, o
// 106 p, q, r

正如您在上面的第一条评论中看到的,有对匹配模式的直接引用。现在,我想捕获 103,它是三个数据字段,但我不想捕获 cmets 中的内容。

我尝试了否定的后视来排除 105 和 106,但我无法想出一个正则表达式来捕获两者。

(?<!//)(\b\d+\b),\s(data),\s(data),\s(data)

这将捕获除 105 之外的所有捕获,但要指定

(?<!//\s*) or (?<!//.*)

因为我试图排除带有任何空格或任何字符的评论会使我的整个正则表达式无效。

我感觉我需要巧妙地使用锚点,或者我需要将我想要的内容封装在一个捕获组中并在我的后视中引用它(例如使用 $1)。


如果这是“正则表达式不支持递归”的另一种情况,因为它是一种正则语言(自动机理论),请指出。

是否可以使用正则表达式排除 103 以及第 105 和 106 行中的 cmets?如果有,怎么做?

【问题讨论】:

  • @duedl0r 这是我今天听到的最愚蠢的话。
  • @Tomalak 你能处理语言无关的抽象吗? :)
  • @duedl0r:正则表达式风格因语言而异,因此必须知道 OP 使用的是哪一种,否则特定解决方案很可能无法正常工作。跨度>
  • 我正在使用 Boost C++ 1.47.0 正则表达式。
  • 这里data是什么意思(?&lt;!//)(\b\d+\b),\s(data),\s(data),\s(data)

标签: regex comments


【解决方案1】:

当您没有正则表达式向前/向后功能时,我刚刚在文本编辑器中使用正则表达式的另一种方法是使用以下序列:

^[^\r\n/]*(/[^/])?[^\r\n/]*(/[^/])?my_search_sequence

它将忽略由非/ 字符分隔的/ 序列,最多2 个。如果您想要更多,那么只需添加更多:

^[^\r\n/]*(/[^/])?[^\r\n/]*(/[^/])?[^\r\n/]*(/[^/])my_search_sequence

等等。

您的搜索词出现在这样的序列后面的概率确实会随着正则表达式的长度而降低。

【讨论】:

    【解决方案2】:

    简单的方法是在开始之前将\s*//.* 替换为空字符串。

    这将从您的输入中删除所有(单行)cmets,您可以继续使用简单的表达式来匹配您实际想要的内容。

    替代方法是使用前瞻而不是后瞻:

    ^(?!//)(\b\d+\b),\s(数据),\s(数据),\s(数据)

    在你的情况下,它甚至可以只锚定正则表达式,因为很明显一行上的第一件事必须是一个数字:

    ^(\b\d+\b),\s(数据),\s(数据),\s(数据)

    一些正则表达式引擎(例如 .NET 中的引擎)支持可变长度的后视,您的似乎无法做到这一点,这就是 (?&lt;!//\s*) 对您失败的原因。

    【讨论】:

    • ^(?!//)(\b\d+\b),^(\b\d+\b),^(\d+),完全相同 - 当您位于行首或数字之间时,\b 将匹配和一个逗号。此外,(?!//)\d 是一种安全的赌注:)
    • @Kobi:是的,这也是我的想法。 ;) 但更一般地说,如果您确切地知道接下来会发生什么,那么消极的前瞻就是要走的路。
    【解决方案3】:

    您可以简单地将正则表达式锚定到行首:

    (?m)^(\d+),\s(\S+),\s(\S+),\s(\S+)
    

    【讨论】:

      【解决方案4】:

      在我看来,您可以将表达式锚定在行首(以获取所有数据):

      ^(\d+),\s(data),\s(data),\s(data)\s*(?://|$)
      

      或者您可以使用可以处理 cmets 的适当 CSV 解析器。

      【讨论】:

        猜你喜欢
        • 2021-12-31
        • 1970-01-01
        • 2012-12-23
        • 2022-12-11
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多