正则表达式以排除标记组或仅匹配标记之间的(。*)

时间:2016-07-29 10:33:26

标签: regex

我现在正在努力使用这个正则表达式。

我需要匹配<ns3:OutputData>数据</ns3:OutputData>之间的文字。

  • 注意:ns后可以是1或2位
  • 注意:数据与示例
  • 中的一行相同
  • 注意:前面和后面的...只是提到有更多嵌套的标签

到目前为止我的正则表达式(ns\d\d?:OutputData>)\b(.*)(\/\1)

示例文字:

...<ns3:OutputData>foo bar</ns3:OutputData>...

我尝试(?:(ns\d\d?:OutputData>)\b)(.*)(?:(\/\1))尝试排除第1组和第3组。

我不想排除匹配的标签,如图片所示:

非常感谢任何帮助。

修改

对于我打算使用正则表达式的Grep Console for IntelliJ可能存在一些正则表达式解释问题。 这是迄今为止最佳匹配的最新图像...

latest

3 个答案:

答案 0 :(得分:2)

基本上,你需要在后面看一看并使用后引用来匹配内容,但不允许使用可变长度外观。幸运的是,您只有2种变体,因此交替处理:

.*?

整个匹配是标签之间的目标内容,可能包含任何内容(包括左尖括号等)。

另请注意不情愿的量词.*,因此匹配在下一个匹配的结束标记停止,而不是贪婪的{{1}},它会匹配到最后一个匹配结束标记。

请参阅live demo

答案 1 :(得分:1)

你的正则表达式几乎就在那里。你需要做的就是让内部匹配器不贪婪。即您可以写(.*)而不是(.*?)

另一个特定于xml的替代方案是否定的字符类:([^<]*)

所以,这是正则表达式:(ns\d\d?:OutputData>)\b(.*?)(\/\1)你可以试验它here

<强>更新

要确保唯一的组是与文本匹配的组,那么您必须使其无需反向引用:(?:ns\d\d?:OutputData>)\b(.*?)<

更新2

可以使用lookbehind仅匹配所需的部件。检查正则表达式here。:

(?<=ns\d:OutputData>)\b([^<]*)|(?<=ns\d\d:OutputData>)\b([^<]*)

说明:

  • 两种选择几乎完全相同。唯一的区别是位数。这很重要,因为有些口味只支持固定长度的外观。
  • 检查另一个,我们将起始标记放在一个后方(?<=...)中,因此它不会包含在完整匹配中。
  • 然后我们贪婪地匹配每个非lt符号:[^<]*。这将停止在第一个结束标记处。

答案 2 :(得分:1)

这就是我的答案:

(?<=(ns\d:OutputData)>)(.*?)(?=<\/\1)

答案基于@WiktorStribiżew3给出的解决方案(在评论中)。 最后一个工作,我稍作修改。

感谢所有人的努力,特别是@WiktorStribiżew!

修改

好的,是的@Bohemian它不匹配2位数,我忘了更新:

(?<=(ns\d{0,2}:OutputData)>)(.*?)(?=<\/\1)