RegEx - MatchCollection获取subMatches

时间:2012-09-11 13:51:31

标签: regex

我有一个这样的文本文件:

Start
<Not Present>

   Start
  <Word>
   End

   Start 
   <Word>
   End

   Start 
   <Antoher>
   End    

End

我必须编写一个regEx,仅提供包含<Word>的“Start ... End”块。

我尝试过这样的事情:

(Start[\s\S]+?(<Word>.*)[\s\S]+?End)

我得到两个子匹配作为结果。 第一个子匹配:

Start
<Not Present>

   Start
  <Word>
   End

第二个子匹配:

   Start 
   <Word>
   End

你可以看到第二个是正确的,但第一个是错的。我只想要<Word>在“开始......结束”块中的子匹配。

我该怎么做?

谢谢。

3 个答案:

答案 0 :(得分:1)

(?s)Start(?:(?!Start|End).)*<Word>(?:(?!End).)*End

(?!Start|End).匹配任何一个字符(包括\n,感谢(?s)修饰符),除非它是StartEnd的第一个字符。这样可以确保您只匹配最里面的StartEnd分隔符。

我在单线模式下使用.(通过内联(?s)修饰符)来匹配任何字符,包括换行符,因为您提到MatchCollection,表示您'重新使用.NET正则表达式的味道。 [\s\S] hack通常只在JavaScript中需要。


更正:我原以为你在谈论.NET框架中的类System.Text.RegularExpressions.MatchCollection,但我刚刚知道VBScript还包含一个名为MatchCollection的类。它可能是你正在使用的VBScript风格(通过ActiveX或COM),所以正则表达式应该是:

Start(?:(?!Start|End)[\S\s])*<Word>(?:(?!End)[\S\s])*End

对此感到抱歉。更多信息here

答案 1 :(得分:0)

两个问题:

  1. 您正在使用“贪婪”的匹配 - 只需添加?即可使其变得非贪婪。如果没有这个,它将匹配跨越两个对的StartEnd - 第一个Start和第二个End - 并将其放在<Word>
  2. 的开头和结尾
  3. 表达式[\s\S]匹配所有内容 - 它与点.相同。您只需要空格[\s]
  4. 试试这个(你也可以删除多余的外括号):

    Start(.*?<Word>.*?)End
    

答案 2 :(得分:0)

[\s\S]没有多大意义。 \s匹配空格,而\S则完全相反 - 它匹配非空格。因此[\s\S]几乎等同于.

我也不确定在.*之后使用<Word>想要实现的目标。这只会匹配<Word>之后的空格。

(Start[\s]+(<Word>)[\s]+End)

据我所知,它适用于http://regexpal.com/中的测试用例。