我有一个数据字段文件,其中可能包含注释,如下所示:
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和它的三个数据字段,但我不想捕获评论中的内容。
我尝试过消极的lookbehind排除105和106,但我无法想出一个正则表达式来捕获它们。
(?<!//)(\b\d+\b),\s(data),\s(data),\s(data)
这将捕获所有但不包括105的捕获,但要指定
(?<!//\s*) or (?<!//.*)
因为我尝试使用任何空格或任何字符排除评论会使我的整个正则表达式无效。
我有一种感觉,我需要狡猾地使用锚点,或者我需要在捕获组中包装我想要的内容并在我的lookbehind中引用它(比如$1
)。
如果这是“正则表达式不支持递归”的另一种情况,因为它是一种常规语言(自动机理论),请指出。
是否可以使用正则表达式排除103和第105和106行中的注释?如果是这样,怎么样?
答案 0 :(得分:6)
最简单的方法是在开始之前用空字符串替换\s*//.*
。
这将从您的输入中删除所有(单行)注释,您可以继续使用一个简单的表达式来匹配您想要的内容。
替代方案是使用预测而不是后视:
^(?!//)(\b\d+\b),\s(data),\s(data),\s(data)
在你的情况下它甚至可以用来锚定正则表达式,因为很明显行上的第一件事必须是一个数字:
^(\b\d+\b),\s(data),\s(data),\s(data)
某些正则表达式引擎(例如.NET中的引擎)支持可变长度的后视,你似乎不具备此功能,这就是(?<!//\s*)
失败的原因。
答案 1 :(得分:1)
在我看来,您可以将表达式锚定在行的开头(以获取所有数据):
^(\d+),\s(data),\s(data),\s(data)\s*(?://|$)
或许您可以使用适当的CSV解析器来处理评论。
答案 2 :(得分:1)
您可以简单地将正则表达式锚定到该行的开头:
(?m)^(\d+),\s(\S+),\s(\S+),\s(\S+)
答案 3 :(得分:0)
当您没有正则表达式的前/后功能时,我刚刚在正则表达式的文本编辑器中使用过的另一种方法是使用以下顺序:
^[^\r\n/]*(/[^/])?[^\r\n/]*(/[^/])?my_search_sequence
它将忽略/
的序列,这些序列最多由2个非/
字符分隔。如果您想要更多,则只需添加更多:
^[^\r\n/]*(/[^/])?[^\r\n/]*(/[^/])?[^\r\n/]*(/[^/])my_search_sequence
以此类推。
您的搜索词出现在这样的序列后面的可能性会随着正则表达式的长度而减小。