【问题标题】:Regex match pattern inside a wrapping pattern包装模式内的正则表达式匹配模式
【发布时间】:2011-03-05 09:29:49
【问题描述】:

我想匹配 > 标签之间的所有电话号码。
这个电话号码的正则表达式:

0[2349]{1}\-[1-9]{1}[0-9]{6}

我厌倦了像 (?=(?:>>)) 这样添加前瞻(和后瞻),但这对我不起作用。

DEMO

【问题讨论】:

  • 这一切都必须用一个 RegExp 完成吗?难道您不能只获取<<(.*?)>> 的所有匹配项,然后使用您当前的正则表达式在其中搜索吗?
  • @shivesh:输入中可以有多少种包装模式?只有一个<<...>> 部分,还是可以有多个?如果有多个,可以嵌套吗?
  • 是的,我更喜欢使用一个正则表达式。
  • @shivesh:你没有回答这个问题。输入中可以有多少个<<...>> 部分?可以有多个吗?如果是,它们可以嵌套吗?
  • @shivesh:“我更喜欢使用正则表达式”..?我完全同意gnarf。使用两个正则表达式使您的解决方案变得简单、简单且易于维护。为什么要尝试将其压缩为一个地狱般的正则表达式?

标签: c# regex


【解决方案1】:
<<0[2349]{1}\-[1-9]{1}[0-9]{6}>>

【讨论】:

  • 你检查过演示吗?它必须支持多行和多个空格。
【解决方案2】:

我前段时间提出了一个类似的问题,用括号([])代替>:

Link here

这应该真的有帮助 干杯

编辑:它应该支持你的演示没问题。

【讨论】:

  • 我想我有一个不同的场景,我需要在另一个模式中匹配一个模式
【解决方案3】:

这可以通过两种正则表达式模式轻松完成:

识别部分:

<<.*>>

对第一个匹配项使用第二个正则表达式:

0[2349]-[1-9]\d{6}

记得设置点来匹配新行。 我知道这不是你要问的,但它会起作用。

【讨论】:

  • 是否可以只使用一个正则表达式?
  • @shivesh,因为公认的答案表明可以在一个正则表达式中完成,但它也显示了正则表达式的最大问题,它们很容易变得非常不可读且难以维护。除非绝对必要,否则我通常会将其分解为更小、更易于理解的模式。
【解决方案4】:

我认为 gnarf(和 Arkain)的建议非常明智——您不必使用一个正则表达式来完成所有工作。

但是,如果您真的想使用一种难以阅读的、不可移植的(仅适用于 .Net,而不适用于其他正则表达式引擎)正则表达式,请使用:

(?<=<<(?:>?[^>])*)0[2349]{1}\-[1-9]{1}[0-9]{6}(?=(?:<?[^<])*>>)

【讨论】:

  • 如果我在输入文本上运行 2 次正则表达式,它的效率会不会低于 1 次正则表达式?
  • 也许吧,但大多数时候,可读性和可维护性比效率上的一些细微差别更重要。此外,我使用的前瞻和后视可能效率很低,因此使用两个正则表达式实际上也可能更快。
【解决方案5】:

以下似乎有效 (as seen on ideone.com):

Regex r = new Regex(@"(?s)<<(?:(?!>>)(?:(0[2349]\-[1-9][0-9]{6})|.))*>>");

每个&lt;&lt;...&gt;&gt; 部分都是一个Match,并且该部分中的所有电话号码都将被捕获到Group[1].Captures

相关问题


模式是如何构造的

首先,我将您的电话号码模式简化为:

0[2349]\-[1-9][0-9]{6}

也就是说,{1} 是多余的,因此它们会被丢弃(参见 Using explicitly numbered repetition instead of question mark, star and plus)。

然后,让我们尝试匹配每个&lt;&lt;...&gt;&gt; 部分。让我们从:

(?s)<<((?!>>).)*>>

这将匹配每个 &lt;&lt;..&gt;&gt; 部分。捕获身体的.* 由负前瞻(?!&gt;&gt;) 保护,这样我们就不会越界。

那么,我们不会匹配.,而是优先匹配您的电话号码。也就是说,我们将.替换为

(phonenumber|.)

然后我只是让一些组不捕获,电话号码捕获到\1,差不多就是这样。 .NET 正则表达式在单个匹配项中存储组的所有捕获,这一事实处理了其余部分。

参考文献

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多