正则表达式匹配包装模式内的模式
我希望匹配包含在<>标签之间的所有电话号码。
这个正则表达式的电话号码:
0[2349]{1}\-[1-9]{1}[0-9]{6}
我厌倦了添加lookahead(和lookbehind)之类的(?=(?:>>))
但这对我不起作用。
DEMO
以下似乎有效( 如ideone.com上所示 ):
Regex r = new Regex(@"(?s)<<(?:(?!>>)(?:(0[2349]\-[1-9][0-9]{6})|.))*>>");
每个<<...>>
部分都是一个Match
,该部分中的所有电话号码都将在Group[1].Captures
。
相关问题
- 有没有正则表达式的味道,我可以计算*和+运算符匹配的重复次数?
如何构建模式
首先,我将您的电话号码模式简化为:
0[2349]\-[1-9][0-9]{6}
也就是说, {1}
是多余的,所以它们被抛弃(参见使用明确编号的重复而不是问号,星号和加号 )。
然后,让我们尝试匹配每个<<...>>
部分。 让我们从:
(?s)<<((?!>>).)*>>
这将匹配每个<<..>>
部分。 捕捉身体的.*
由负向前瞻(?!>>)
守护,这样我们就不会走出界限。
然后,而不是匹配.
,我们优先考虑匹配您的电话号码。 也就是说,我们取而代之.
同
(phonenumber|.)
然后我简单地让一些群组不捕获,并且电话号码捕获到\1
,这就是它。 .NET regex在一次匹配中存储由组进行的所有捕获的事实解决了其余的问题。
参考
- regular-expressions.info/Lookarounds和Grouping
我前段时间使用方括号([])而不是<< >>放置了类似的问题:
链接在这里
这应该真的有助于干杯
编辑:它应该支持你的演示没有问题。
这可以通过两个正则表达式模式轻松完成:
识别部分:
<<.*>>
在第一个匹配项上使用第二个正则表达式:
0[2349]-[1-9]\d{6}
请记住将点设置为匹配新行。 我知道这不是你要求的,但它会起作用。
我认为gnarf(和Arkain的)建议是非常明智的 – 你不必使用一个正则表达式完成所有的工作。
但是,如果你真的想要使用一个难以读取的不可移植(仅在.Net中工作,而不是在其他正则表达式引擎中)正则表达式,请转到:
(?<=<<(?:>?[^>])*)0[2349]{1}\-[1-9]{1}[0-9]{6}(?=(?:[^<])*>>)
<<0[2349]{1}\-[1-9]{1}[0-9]{6}>>