正则表达式从捕获中排除匹配

时间:2010-07-27 18:08:35

标签: c# regex

在.Net中使用Regex

我将拥有一组类似这样的数据

< Bunch o' Data Here >

其中<只是新记录的指标,>是记录的结尾。

这些记录可能会像这样出现

< Dataset 1><Dataset 2 broken, no closing tag <dataset 3>

他们也可以作为

进来
< Dataset 1>Dataset 2 broken, no opening tag ><dataset 3>

尽管如此,我不确定后一种情况是否可行,而且当我必须时,我会越过那座桥。

我正在尝试使用正则表达式将这些基于此开始和结束字符分成记录,最终是这样的

Match 1 = < Dataset 1>
Match 2 = <Dataset 2 broken, no closing tag 
Match 3 = <Dataset 3>

我试图找出非捕获组如何工作,也许我的理解是错误的。

<.*?(?:<|>)

让我非常接近,我认为,除了它包括第三组数据的开头字符和第二组的捕获。 我还怀疑?:没有做它需要的东西,如果它取出它,它会返回相同的匹配集(2)。

5 个答案:

答案 0 :(得分:7)

看起来你已经翻了。您需要使用?:来捕获群组,而不是:?

 <.*?(?:<|>)

要进行扩展:捕获组中的?运算符表示您要执行特殊操作。 :表示不捕获,但是您可以为?提供其他操作数以执行其他操作。常见的是前瞻(?=)和后瞻(?<),但还有很多其他。

我也刚刚意识到你想要匹配的范围(超出非捕获问题)。匹配的parens / bracket / etc的语言不规则,所以 - 假设我正确理解你的目的 - 你需要创建一个相当复杂的扩展正则表达式,以匹配你想要的。关于此问题还有其他几个问题,包括this one,其中有一些讨论。

答案 1 :(得分:1)

如此简单的事情:&lt; [^&lt;&gt;] +&gt; | [^&lt;&gt;] +&gt; |&lt; [^&lt;&gt;] +

答案 2 :(得分:1)

我认为你要找的是 lookahead ,而不是非捕获组。但只是将:?(原文如此)更改为?=不会使正则表达式正常工作。如果在结束>和下一个<之间从未发过任何文字,请尝试以下操作:

<?[^<>]+>?(?=(?:<|$))

如果缺少结束>,则会有效,但如果缺少开头<则不行。

答案 3 :(得分:1)

我想我找到了一个更简单的解决方案

\<.*?(\>|(?=\<)|$)

似乎有效。 我逃脱了&lt; &GT;标志的一致性

编辑:添加$以允许在字符串

结尾处取消终止

答案 4 :(得分:0)

正则表达式可能是这项工作的错误工具。

我对此的初衷是将regexreplace嵌入其他某种语言中,并分阶段进行,以便您可以了解3年后的工作。

如果您可能错过了>

  • 第一遍将行括在\ <的开头,并在结尾的>。
  • 第二遍,用单个令牌替换[<>] +。也就是说,任何数量的开始/停止令牌都将替换为单个令牌。第一步中放上了额外令牌的任何东西现在都已修复。
  • 您的第三遍密码将id字符串放在第一个令牌之前的开头。 ID是用户代码和行号
  • 您的最终遍历实际上是将字符串分割成数据集,但是如果它得到的数据集数量不正确-太多或太少,或者未通过某些验证检查,则可以将整个行吐给创建者/编辑者带有“问题:您缺少数据字段”。或其他照明错误。