Regex 我对这个意外的负前瞻子模式犯了什么错误?

Regex 我对这个意外的负前瞻子模式犯了什么错误?,regex,regex-negation,regex-lookarounds,negative-lookahead,Regex,Regex Negation,Regex Lookarounds,Negative Lookahead,实际上,我正在使用一个.tsv数据库,它的标题中充满了对我有意义的东西 因此,我想将它们从标题中删除,以使我和其他用户(不熟悉关系数据库,因此我们最终大多使用Excel来组织数据和处理数据)能够通过使用选项卡来处理Excel 示例标题: >(name1)database-ID:database2-ID:value1:value2 (我知道将值放在标题中似乎很奇怪,但这是对与标题关联的第三个值的参数的描述,我们不必在这里弄乱) 输出为: name1\tdatabase-ID\tdataba

实际上,我正在使用一个
.tsv
数据库,它的标题中充满了对我有意义的东西

因此,我想将它们从标题中删除,以使我和其他用户(不熟悉关系数据库,因此我们最终大多使用Excel来组织数据和处理数据)能够通过使用选项卡来处理Excel

示例标题:

>(name1)database-ID:database2-ID:value1:value2
(我知道将值放在标题中似乎很奇怪,但这是对与标题关联的第三个值的参数的描述,我们不必在这里弄乱) 输出为:

name1\tdatabase-ID\tdatabase2-ID\tvalue1\tvalue2\n
因此,我用EmEditor(BOOST语法)粘贴了我的数据(标题,每行一个),并附带了以下正则表达式:

 >\((.*)\)(.*?)\:(.*?)\:(.*?)\:(.*?)\n
然后通过在每个捕获组之间插入选项卡将每个捕获组与其他组分开。它工作正常,匹配完美,没问题

但我意识到有一些格式错误的行不符合整个数据库的逻辑,我想用一个表达式立即将它们分开

如果我用了错误的台词,它将是:

>(name1)database-ID:database2-ID:value1-1:value1-2\n
>(name2)database-ID:database2-ID:value2-1:value2-2\n
>(name3)database-ID:database2-ID:value3-1value3-2\n
最后一行格式不正确,因为它缺少最后两个值之间的
。 我希望通过围绕识别格式良好的线条的原始表达式进行匹配

我完全知道,我可以通过稍微调整我的第一个表达式来获得不同的解决方案,以消除好的行并在一行之后检索不正确的行 我不想为我的过程找到解决方案,我只想了解我在那里做得不好的地方;因此,我受到了更多的教育(而不仅仅是因为能够规避我无法解决的错误而变得更加狡猾):

我试图否定上述表达:

([^(>\((.*)\)(.*?)\:(.*?)\:(.*?)\:(.*?)\n)])
那跟什么都不匹配

我尝试了一个消极的前瞻,但它将非常缓慢,然后将匹配文档中可能的每一个0长度匹配:

(?!(^>\((.*)\)(.*?)\:(.*?)\:(.*?)\:(.*?)\n))
因此,我在后面添加了一个字符串的组捕获, 但它也不起作用:

(?!(^>\((.*)\)(.*?)\:(.*?)\:(.*?)\:(.*?)\n))(^.*?)

所以,请解释一下我在否定组(
[^whatever]
)和否定前瞻的用法上的错误在哪里?

你可以通过动词来实现这一点。下面的正则表达式将匹配所有错误行

(?:^>\([^()]*\):[^::*:[^::*:[^:*:[^:*:[^:\n]*$)(*跳过)(*F)|^+

所以,请解释一下我在否定组(
[^whatever]
)和否定前瞻的使用上哪里出错了

让我们首先解决这个问题:
[^(模式)]
做什么

你似乎有一个误解,并期望它:

  • 匹配除子模式
    模式
    之外的所有内容。(否定)
它实际上做的是:

  • 匹配任何非
    p
    a
    t
    ,…
    n
因此,模式

([^(>\(.*)(.*?\:(.*?\:(.*?\:(.*?\:(.*?)\n)])
。。。匹配的字符不是
,…
\n


至于消极前瞻,你只是做错了。锚定
^
处于错误的位置,因此你的断言将无法提供任何有用的帮助。消极前瞻也不是什么意思

(?!(^>\(.*)(.*)\:(.*):(.*):(.*):(.*):(.*)\n))
我将解释它的作用:

  • (?!
    打开反向前瞻组:断言位置与此模式不匹配,而不移动指针位置
  • 捕获组。在负前瞻组中使用捕获组是无用的,因为负前瞻组中的子模式从不匹配
  • ^
    在字符串开头断言位置
  • \(
    文字字符序列“>(”
  • (.*)
    捕获组,该组匹配尽可能多的字符(新行除外),然后返回
  • \)
    文字字符“”
  • (.*?)
    捕获任何字符(换行符除外)的零对一匹配的组
  • \:
    文字字符:“
  • (.*?\:(.*?\:(.*?)
  • \n
    新行
  • 关闭捕获组
  • 关闭负前瞻组。此断言完成后,指针位置与开始位置相同,因此结果匹配的长度为零
请注意,定位点嵌套在负前瞻组中。它应位于开始位置:

^(?(!(>\(.*)(.*):(.*):(.*):(.*):(.*):(.*)\n))
虽然这不会返回任何有用的信息,但它解释了问题所在,因为您不需要解决方案

如果您突然需要解决方案,请参考我的相关答案(我不会在帖子中添加任何其他内容):


基于我所阅读的内容
这就是我在emEditor的目的:

^(?!>\([A-Za-z0-9\-]*?)\([A-Za-z0-9\-]*?):{3}([A-Za-z0-9\-]*?)\n.*\n
(name1)数据库ID:database2 ID:value1-1:value1-2
(不匹配)
>(名称2)数据库ID:database2 ID:value2-1:value2-2
(不匹配)
>(名称3)数据库ID:database2 ID:value3-1value3-2
(比赛)
>(名称3)数据库ID::database2 ID:value3-1:value3-2
(匹配)
(character类避免丢弃包含特殊字符的名称,而不允许有两个后续的
:“

我还可以通过以下方式获得相同的结果:

(?!^>\(([A-Za-z0-9_\'\-]*?)\)(([A-Za-z0-9_\'\-]*?)\:){3}([A-Za-z0-9_\'\-]*?)\n)^.*\n
所以我想,一直以来,抓捕群体都是我的前瞻性的障碍

现在我承认使用
(*SKIP)(*F)| ^.+
模式效率更高,只是我不知道这些函数,我